Rails: запрос для получения последних элементов на основе метки времени полиморфной ассоциации - PullRequest
1 голос
/ 13 сентября 2010

У меня есть обычные полиморфные ассоциации для комментариев:

class Book < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

class Article < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

class Comment < ActiveRecord::Base
    belongs_to :commentable, :polymorphic => true
end

Я хотел бы иметь возможность определять Book.recently_commented и Article.recently_commented на основе метки времени метки create_at комментариев.Сейчас я смотрю на довольно уродливый запрос find_by_SQL, чтобы сделать это с помощью вложенных выборок.Кажется, что в Rails должен быть лучший способ сделать это, не прибегая к SQL.

Есть идеи?Спасибо.

Для чего это стоит, вот SQL:

select * from 
    (select books.*,comments.created_at as comment_date 
    from books inner join comments on books.id = comments.commentable_id 
    where comments.commentable_type='Book' order by comment_date desc) as p 
group by id order by null;

Ответы [ 2 ]

2 голосов
/ 13 сентября 2010

Иногда лучше всего добавить поле к объекту, который вы комментируете. Например, поле commented_at типа datetime. Когда комментарий сделан к объекту, просто обновите это значение.

Хотя для этого можно использовать SQL, метод commented_at может оказаться гораздо более масштабируемым.

1 голос
/ 13 сентября 2010

Не уверен, как ваш метод выглядел ранее, но я бы начал с:

class Book < ActiveRecord::Base

  def self.recently_commented
    self.find(:all, 
              :include => :comments, 
              :conditions => ['comments.created_at > ?', 5.minutes.ago])
  end
end

Это должно найти все книги, для которых был создан комментарий за последние 5 минут.(Возможно, вы также захотите добавить ограничение).

Я также хотел бы создать базовый класс для этой функции, чтобы избежать повторения кода:

class Commentable < ActiveRecord::Base
  self.abstract_class = true

  has_many :comments, :as => :commentable

  def self.recently_commented
    self.find(:all, 
              :include => :comments, 
              :conditions => ['comments.created_at > ?', Time.now - 5.minutes])
  end
end

class Book < Commentable
end

class Article < Commentable
end

Также выхочу посмотреть на использование плагина для достижения этой цели.Например, act_as_commentable .

...