2010-10-12 41 views
2

使用Rails 3,这个范围会如预期:如何创建一个范围来查找“作者谁拥有零职位”?

 scope :with_posts, lambda { 
     joins(:posts). 
     select("authors.*, count(posts.id) posts_count"). 
     group("posts.author_id"). 
     having("posts_count > 0") 
     } 

生成的SQL是:

SELECT authors.*, count(posts.id) posts_count FROM `authors` INNER JOIN `posts` ON `posts`.`author_id` = `author`.`id` GROUP BY posts.author_id HAVING posts_count > 0 

但其逆不返回任何结果:

 scope :with_posts, lambda { 
     joins(:posts). 
     select("authors.*, count(posts.id) posts_count"). 
     group("posts.author_id"). 
     having("posts_count < 1") 
     } 

我假设没有帖子的作者根本没有被第三行选中......那么解决方案是什么?

回答

1

你是对的,连接是排除所有作者与零职位,你需要的是一个外部连接。

我不知道rails 3语法,但在rails 2中,您可以用SQL片段指定连接语句,而不是简单地使用关系名称。
User.all(:joins => 'outer join posts on users.id = posts.user_id')
Rails 3必须有一个等价的符号,但我从来没有使用它,所以我不知道确切的语法。这应该是一般的想法。

1

由于正在创建内部连接SQL,它将显示两个表中可用记录的结果。因此,尝试建立外部连接,并找到/在邻桌算空值

尝试外连接

0

我不知道这么多,但我会建议你看看这个Railscast

希望这适合你。

0
scope :without_posts, lambda { 
    where("id NOT IN (?)", Posts.select("author_id").group("author_id")) 
} 

如果您的数据库中有author_id索引,这将最适用。