1

我对评论有通常的多态关联:

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

我希望能够根据评论上的 created_at 时间戳定义 Book.recently_commented 和 Article.recently_commented。现在我正在查看一个非常丑陋的 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;
4

2 回答 2

2

有时最好向您正在评论的对象添加一个字段。就像可能是 datetime 类型的 commented_at 字段。当对对象发表评论时,只需更新该值。

虽然可以使用 SQL 来执行此操作,但 commented_at 方法可能被证明更具可扩展性。

于 2010-09-13T16:26:42.400 回答
1

不确定您的方法以前是什么样的,但我会从以下开始:

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

此外,您可能想看看使用插件来实现这一点。例如acts_as_commentable

于 2010-09-13T16:45:36.120 回答