高级Rails 3范围与CROSS JOIN

时间:2012-09-07 15:55:56

标签: ruby-on-rails join scope

我想要一个范围,它返回一个他们有章节的(例如)书籍清单。我找到了this post

它帮助我选择了他们有章节的书籍。但如果我想要选择那些他们没有章节的话:

    class Book
      scope :long, joins(:chapters).
        select('books.id, count(chapters.id) as n_chapters').
        group('books.id').
        having('n_chapters = 0')
    end

此范围不会给我任何回报。你能救我一下吗?

1 个答案:

答案 0 :(得分:2)

使用joins会导致与已连接的书籍+章节的所有组合创建关系。这是通过INNER JOIN SQL子句完成的。如果您想要创建所有可能的组合(包括书籍+无效章节),您必须制作OUTER JOIN

替换

joins(:chapters).

joins('LEFT OUTER JOIN chapters ON books.id=chapters.book_id').

在这种情况下,请考虑使用NOT IN SQL子句。像这里:

scope :long, lambda { where('id NOT IN (%s)' % Chapter.select(:book_id).to_sql) }

它相当小/更快,更易读/可维护。