Сортировка по свойствам ассоциации has_many - PullRequest
2 голосов
/ 09 июля 2010

Предположим, Song s have_many Comment s; Как я могу:

  1. Вытащить список всех песен из базы данных, отсортированный по количеству комментариев, которые у них есть? (Т.е. песня с наибольшим количеством комментариев первой, песня с наименьшим количеством комментариев последней?)
  2. То же самое, но отсортировано по времени создания комментария? (Т.е. песня с последним созданным комментарием первой, песня с последним созданным комментарием последней?)

Ответы [ 2 ]

6 голосов
/ 09 июля 2010

1) Есть несколько способов сделать это, самым простым будет счетчик кеша, вы сделаете так, чтобы я создал столбец для поддержания количества и рельсов, чтобы счет продолжался. столбец в этом случае будет comments_count

songs = Song.all(:order => "comments_count DESC")

ИЛИ вы можете сделать шикарный запрос:

songs = Song.all(:joins => "LEFT JOIN comments ON songs.id = comments.song_id",
                 :select => "song.name, count(*)",
                 :group => "song.name",
                 :order => "count(*) DESC")

несколько предостережений со вторым методом, все, что вы хотите выбрать в песнях, вам нужно будет включить в группу по утверждению. Если вам нужно только тянуть песни с комментариями, то вы можете:

songs = Song.all(:joins => :comments, 
                 :select => "song.name, count(*)",
                 :group => "song.name",
                 :order => "count(*) DESC")

Что выглядит лучше, но поскольку это внутреннее соединение, вы не получите песни без комментариев

2) просто включить / объединить

songs = Song.all(:include => :comments, :order => "comment.created_at"

Надеюсь, это поможет!

1 голос
/ 09 июля 2010

Если вам нужно отсортировать по количеству комментариев, которые они имеют - хотя вы можете сделать это напрямую с помощью SQL - я настоятельно рекомендую использовать counter_cache - См .: http://railscasts.com/episodes/23-counter-cache-column

После этого просто установите порядок с помощью опции find, например:

Song.all(:order => "comments_count DESC");

Это отличается от Rails 3, поэтому это зависит от того, что вы используете.

Я бы также порекомендовал кэшировать последний созданный комментарий в модели Song, чтобы облегчить вам жизнь.

Вы могли бы сделать это с помощью обратного вызова after_save для модели Comment с чем-то вроде:

self.song.update_attributes!({:last_comment_added_at => Time.now.to_s(:db)})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...