我有一个评论表和一个职位表,其中职位有很多评论和评论属于一个职位(即它有一个post_id在表中)。Rails ActiveRecord:选择职位没有评论
如何有效选择最后10个没有评论的帖子。 如果没有首先选择所有帖子并检查每个0评论数,我似乎无法完成此操作。
在此先感谢您的帮助。
-Nathan
我有一个评论表和一个职位表,其中职位有很多评论和评论属于一个职位(即它有一个post_id在表中)。Rails ActiveRecord:选择职位没有评论
如何有效选择最后10个没有评论的帖子。 如果没有首先选择所有帖子并检查每个0评论数,我似乎无法完成此操作。
在此先感谢您的帮助。
-Nathan
您可以将counter cache添加到Comment
模型和一对夫妇的named scopes到Post
模型。喜欢的东西:
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解释更多。
你会以某种方式添加一个条件是这样的:
:conditions => '(SELECT count(*) FROM comments WHERE post_id = #{id}) = 0'
我不是SQL方面的专家,所以也许有什么东西像一个空的关键字左右。
你可以做
Post.find(:all, :include => :comments, :conditions => "comments.id is null", :limit => 10, :order => "created_at desc")
一个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
你需要的是一个左外连接:
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
Post.includes(:评论)。凡(“评论.id为空“)
对于这个问题,您应该使用双引号才能替换#{id} – 2010-06-06 09:01:47
更好的是不要这么做,因为它可能会将您的代码打开到SQL注入。这样做:conditions => ['(SELECT ... WHERE post_id =?)= 0',id] – hurikhan77 2010-06-06 09:16:56
@ hurikhan77:你说得对。我指的是一个ActiveRecord关系,在我写的时候可以这样做。 – fphilipe 2010-06-07 10:32:08