Для этого вы можете использовать плагин voice_fu (используйте kandadaboggu-voice_fu версия)
class User
acts_as_voter
end
Добавить vote_total
столбец (целое число) к posts
таблице.
class Post
acts_as_voteable :vote_counter => true
end
Теперь вы можете делать следующее:
user.vote_for(post) # vote up
user.vote_against(post) # vote down
post.vote_total # sum of +ve and -ve votes
post.vote_count # count of votes
Если вы используете директиву vote_counter
, общее количество голосов сохраняется в таблице posts
. Для вычисления vote_total
дополнительный SQL не требуется.
Чтобы отсортировать посты по voice_total, выполните следующие действия:
Posts.all(:order => "vote_total DESC")
Раскрытие
Я поддерживаю kandadaboggu-vote_fu
драгоценный камень.
Редактировать
Чтобы реализовать это в вашей текущей схеме, вы можете сделать следующее:
Post.all(:joins => :votes, :select => "posts.*, count(*) as vote_total",
:group => "votes.post_id", :order => "vote_total DESC", :limit => 10)
Редактировать 2
Вы можете использовать следующий код для реализации этой функции для работы с текущей логикой.
Обратите внимание, что Rails использует соединения INNER, поэтому сообщение не будет выбрано, если у него нет голосования. Вы можете обойти это, всегда голосуя один раз при создании сообщения.
Я исправил ваш paginate
звонок. Нынешняя логика крайне неэффективна. Разбивка на страницы применяется к массиву, возвращенному из БД, поэтому весь набор результатов загружается перед выполнением разбивки на страницы. Как правило, обрабатывайте paginate
как метод all
с двумя дополнительными параметрами.
Обратите внимание, что приведенный ниже SQL будет сильно напрягать ресурсы вашей системы. Возможно, вам придется оптимизировать, сохранив vote_total
в таблице posts
.
conditions, joins = {}, :votes
unless(params[:tag_name] || "").empty?
conditions = ["tags.tag_name = ? ", params[:tag_name]]
joins = [:tags, :votes]
end
@posts=Post.paginate(
:select => "posts.*, count(*) as vote_total",
:joins => joins,
:conditions=> conditions,
:group => "votes.post_id",
:order => "vote_total DESC",
:page => params[:page], :per_page => 5)
Редактировать 3
Логика для голосования при создании поста.
class Vote
belongs_to :user
belongs_to :post
end
class Post
belongs_to :user
after_create :self_vote
def self_vote
# I am assuming you have a user_id field in `posts` and `votes` table.
self.votes.create(:user => self.user)
end
end
Код итерации для сообщений:
<% @posts.each do |post| %>
<p><%= link_to(post.title, post_path(post)) %></p>
<p>
Created <%= time_ago_in_words(post.created_at) %>.
Votes <%= post.vote_total %>
</p>
<% end %>