2010-06-06 63 views
2

我有一个评论表和一个职位表,其中职位有很多评论和评论属于一个职位(即它有一个post_id在表中)。Rails ActiveRecord:选择职位没有评论

如何有效选择最后10个没有评论的帖子。 如果没有首先选择所有帖子并检查每个0评论数,我似乎无法完成此操作。

在此先感谢您的帮助。

-Nathan

回答

3

您可以将counter cache添加到Comment模型和一对夫妇的named scopesPost模型。喜欢的东西:

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的例子中,我包括在:recent范围posts表名。如果两个表具有相同的列名,这是一个很好的练习,以避免在SQL查询中出现不明确的列名。 This Railscast解释更多。

0

你会以某种方式添加一个条件是这样的:

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

我不是SQL方面的专家,所以也许有什么东西像一个空的关键字左右。

+0

对于这个问题,您应该使用双引号才能替换#{id} – 2010-06-06 09:01:47

+2

更好的是不要这么做,因为它可能会将您的代码打开到SQL注入。这样做:conditions => ['(SELECT ... WHERE post_id =?)= 0',id] – hurikhan77 2010-06-06 09:16:56

+0

@ hurikhan77:你说得对。我指的是一个ActiveRecord关系,在我写的时候可以这样做。 – fphilipe 2010-06-07 10:32:08

8

你可以做

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

Post.includes(:评论)。凡(“评论.id为空“)