query:has_many其中所有子字段都是nil
我正在使用Rails 3.2与ActiveRecord和MySQL,我有一对多关联的模型:
class Author has_many :books end class Book belongs_to :author attr_accessible :review end
我想找到没有审查所有书籍的作者。 我试过了:
Author.includes(:books).where('book.review IS NIL')
但显然没有用,因为它找到的作者至少有一本书没有经过审查。 我应该使用什么查询?
SQL非常简单:
SELECT authors.name, count(books.review is not null) FROM authors LEFT JOIN books ON (authors.id=books.author_id) GROUP BY authors.name HAVING count(books.review) == 0
将它翻译成AR查询语言可能需要一些时间……好吧,所以它看起来像这样:
Author.count('books.review', joins: :books, select: 'name', group:'name', having: 'count_books_review=0')
至于我,SQL看起来不那么奇怪了;-)
基于WRz答案,我准备了自己的查询:
Author.joins(:books).group('authors.id').having("count(books.reviews)=0")
它更适合我,因为它返回AR Relation(并且WRz的查询返回一个Hash)。
试试这个
Author.joins(:books).where('books.review is null')
编辑:这将获取所有作者至少有一本书没有审查。 我刚刚意识到你的问题有点不同。
这将是这样的。
Authors.joins(:books).select('authors.*, count(books.id) as total_books, count('books.review is null') as books_without_review.group('authors.id').having(total_books == books_without_review)
PS:这不是确切的语法,并且未经测试
请尝试以下代码。
class Author has_many :books end class Book belongs_to :author attr_accessible :review end authors = Author.all.collect do |author| if author.books.where(:review => nil).size == author.books.size author end end authors.compact!
在此代码之后,作者将是一个包含所有未经审阅的书籍的作者的数组。 另请注意,我将Book
模型中的作者关联更改为belongs_to
而不是has_one
。 在一方拥有has_many
关系而在另一方拥有has_many
关联总是一个好习惯。