2010-03-05 169 views
1

需要SQL/ActiveRecord查询的一点帮助。比方说,我有这样的:正确的ActiveRecord连接查询帮助

Article < ActiveRecord::Base 
    has_many :comments 
end 

Comment < ActiveRecord::Base 
    belongs_to :article 
end 

现在我想显示“最近讨论”文章的列表 - 这意味着我要拉的所有文章,包括加入到他们每个人的最后意见。然后我想通过评论的created_at属性对文章列表进行排序。

我看过Railscast的include/joins - 非常好,但还是有点难住。

我想,我想用一个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,红宝石1.8.7

有什么建议? :)

回答

0

你有两个解决方案。

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最后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

+0

对不起,我应该在这里更加明确 - 就是我要找的是不是以显示与最近的评论文章。我期待显示在其最新或最新评论日期之前订购的所有文章的列表。也许这可以在远处编辑来满足这个?感谢您的时间和帮助! – Betsy 2010-03-06 00:39:34

+0

可能是这样的: named_scope:recent_commented,,:include => {:comments,{:order =>“comments.created_at DESC”,:limit => 1}},:order =>“comments。 created_at DESC“ 这显然不起作用 - 尤其是因为我仍然试图理解正确的嵌套。 – Betsy 2010-03-06 00:42:42

+0

这是我的部分。范围'Article.recently_commented'返回最近评论的文章。 – 2010-03-06 00:48:55

0

你会不得不做一些额外的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" }} 

您需要使用:连接代替:包括否则Rails会忽略你:选择选项。另外不要忘记使用:group选项来避免重复的记录。您的结果将包含#last_comment_datetime访问者,该访问者将返回最后评论的日期时间。如果该文章没有评论,它将返回该文章的created_at。

编辑:命名范围现在使用的λ

+1

在你的代码中,'24.hours。前'将被设置为第一次加载模型的时间。你必须为此使用'lambda'。 – 2010-03-06 01:14:22

+1

+1对于非常有用的SQL!但我不能B/C我是一个新手。有人可以分享爱,直到我得到15分? – Betsy 2010-03-06 02:01:18

+0

不要害怕SQL :) – 2010-03-06 02:14:48