Простой вопрос ActiveRecord - PullRequest
1 голос
/ 28 июня 2011

У меня настроена модель базы данных, в которой у поста много голосов, у пользователя много голосов, а пост принадлежит как пользователю, так и посту.Я использую функцию разбивки на страницы и пытаюсь создать фильтр, чтобы пользователь мог отсортировать сообщение либо по дате, либо по количеству голосов, которые имеет сообщение.Опция даты проста и выглядит следующим образом:

@posts = Post.paginate :order => "date DESC"

Однако я не могу понять, как сделать порядок для голосов.Если бы это был SQL, я бы просто использовал GROUP BY в столбце голосования user_id вместе с функцией count, а затем я бы соединил результат с таблицей сообщений.

Как правильно использовать ActiveRecord?

Ответы [ 2 ]

2 голосов
/ 29 июня 2011

1) Используйте механизм кэширования счетчиков для хранения подсчета голосов в модели Post.

# add a column called votes_count
class Post
  has_many :votes
end

class Vote
  belongs_to :post, :counter_cache => true
end

Теперь вы можете отсортировать модель Post по подсчету голосов следующим образом:

Post.order(:votes_count)

2) Используйте group.

Post.select("posts.*, COUNT(votes.post_id) votes_count").
  join(:votes).group("votes.post_id").order(:votes_count)

Если вы хотите включить в набор результатов сообщения без голосов, тогда:

Post.select("posts.*, COUNT(votes.post_id) votes_count").
  join("LEFT OUTER JOIN votes ON votes.post_id=posts.id").
  group("votes.post_id").order(:votes_count)

Я предпочитаю подход 1, так как он эффективен, а стоимость подсчета голосов загружена вперед (т. Е. При голосовании).

1 голос
/ 28 июня 2011

Просто выполните все обычные операции с SQL как часть запроса с параметрами.

@posts = Post.paginate :order => "date DESC", :join => " inner join votes on post.id..." , :group => " votes.user_id"

http://apidock.com/rails/ActiveRecord/Base/find/class

Так что я не знаю много о ваших моделях, но вы, кажется, знаете кое-что о SQL, поэтому

именованные области: вы просто помещаете запрос в метод класса:

named_scope :index , :order => 'date DESC', :join => .....

но они могут принимать параметры

named_scope :blah, {|param| #base query on param }

для вас, особенно если вы более знакомы с SQL, вы можете написать свой собственный запрос,

@posts = Post.find_by_sql( <<-SQL ) 
  SELECT posts.*
  ....
SQL
...