Правильный ActiveRecord присоединяется к помощи запроса - PullRequest
1 голос
/ 06 марта 2010

Нужна небольшая помощь с запросом SQL / ActiveRecord. Допустим, у меня есть это:

Article < ActiveRecord::Base
  has_many :comments
end

Comment < ActiveRecord::Base
  belongs_to :article
end

Теперь я хочу отобразить список «Недавно обсужденных» статей, то есть я хочу получить все статьи и включить последний комментарий, который был добавлен к каждой из них. Затем я хочу отсортировать этот список статей по атрибуту create_at комментария.

Я наблюдал за Railscast на include / join - очень хорошо, но все еще немного озадачен.

Я думаю, что хочу использовать named_scope, кое-что для этого:

Article < ActiveRecord::Base
  has_many :comments

  named_scope :recently_commented, :include => :comments, :conditions => {   some_way_to_limit_just_last_comment_added }, :order => "comments.created_at DESC"
end

Использование MySQL, Rails 2.3.4, Ruby 1.8.7

Есть предложения? :)

Ответы [ 2 ]

0 голосов
/ 06 марта 2010

Для этого вам понадобится дополнительный SQL:

named_scope :recently_commented, lambda {{
  :select => "articles.*, IFNULL(MAX(comments.created_at), articles.created_at) AS last_comment_datetime",
  :joins => "LEFT JOIN comments ON comments.article_id = articles.id",
  :group => "articles.id",
  :conditions => ["last_comment_datetime > ?", 24.hours.ago],
  :order => "last_comment_datetime DESC" }}

Вам нужно использовать: joins вместо: include, в противном случае Rails проигнорирует ваш вариант: select.Также не забудьте использовать опцию: group, чтобы избежать дублирования записей.Ваши результаты будут иметь метод доступа #last_comment_datetime, который будет возвращать дату и время последнего комментария.Если к статье не было комментариев, она вернет созданную статью.

Редактировать: в именованной области теперь используется лямбда

0 голосов
/ 06 марта 2010

У вас есть два решения для этого.

1) Вы рассматриваете n recent как n last. Тогда вам не нужно ничего фантастического:

Article < ActiveRecord::Base   
  has_many :comments

  named_scope :recently_commented, :include => :comments, 
                :order => "comments.created_at DESC",
                :limit => 100 
end

Article.recently_commented # will return last 100 comments

2) Вы относитесь к последним как к последнему x продолжительности.

Для ясности определим недавний как что-то, что было добавлено за последние 2 часа.

Article < ActiveRecord::Base   
  has_many :comments

  named_scope :recently_commented, lambda { { 
                    :include => :comments, 
                    :conditions => ["comments.created_at >= ?", 2.hours.ago]
                    :order => "comments.created_at DESC",
                    :limit => 100 }} 

end

Article.recently_commented # will return last 100 comments in 2 hours

Примечание Код выше будет загружать комментарии, связанные с каждой выбранной статьей. Используйте :joins вместо :include, если вам не нужна энергичная загрузка.

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