Rails ActiveRecord:选择没有评论的帖子

时间:2010-06-06 08:53:00

标签: ruby-on-rails activerecord model

我有一个评论表和一个帖子表,其中帖子有很多评论,评论属于一个帖子(即表格中有一个post_id)。

如何有效地选择没有评论的最后十个帖子。 如果没有先选择所有帖子并检查每个帖子的0评论数,我似乎无法做到这一点。

提前感谢您的帮助。

-Nathan

6 个答案:

答案 0 :(得分:8)

你可以做到

Post.find(:all, :include => :comments, :conditions => "comments.id is null", :limit => 10, :order => "created_at desc")

答案 1 :(得分:3)

您可以向Comment模型添加counter cache,向Post模型添加几个named scopes。类似的东西:

class Post < ActiveRecord::Base
  has_many :comments

  named_scope :recent, :limit => 10, :order => 'created_at DESC'
  named_scope :uncommented, :conditions => { :comments_count => 0 }
end

class Comment < ActiveRecord::Base
  belongs_to :post, :counter_cache => true
end

如果您使用的是Rails 3,那么命名的范围语法会略有不同:

class Post < ActiveRecord::Base
  has_many :comments

  scope :recent, limit(10).order('posts.created_at DESC')
  scope :uncommented, where(:comments_count => 0)
end

现在,您可以通过将命名范围链接在一起来查找没有任何注释的帖子:

@uncommented = Post.recent.uncommented

如果你想获得所有帖子而没有任何评论(即不仅仅是最近的十篇帖子),那么它将是:

@uncommented = Post.uncommented

- 您可能已经注意到,在Rails 3示例中,我在posts范围中包含了:recent表名。这是一个很好的做法,以便在两个表具有相同列名的情况下避免SQL查询中的模糊列名。 This Railscast解释了更多。

答案 2 :(得分:1)

在帖子表中添加comments_count列,让迁移更新计数器。从现在开始,如果您在关联上提供:counter_cache => true,Rails将自动更新您的计数器。现在很容易选择最后10个帖子:

Post.find_all_by_comments_count 0, :order => 'created_at DESC', :limit => 10

文档链接:http://rails.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001318

答案 3 :(得分:0)

您必须以某种方式添加条件:

:conditions => '(SELECT count(*) FROM comments WHERE post_id = #{id}) = 0'

我不是SQL方面的专家,所以也许有类似EMPTY关键字的东西。

答案 4 :(得分:0)

您需要的是左外连接:

Post.all :joins => "left outer join comments on posts.id = comments.post_id", :conditions => "comments.id is null", :limit => 10, :order => 'created at desc'

此链接可帮助您了解不同类型的SQL连接:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

答案 5 :(得分:0)

Post.includes(:comments).where(“comments.id为null”)