query: has_many where all the child fields are nil

安稳与你 提交于 2019-12-11 13:52:55

问题


I'm using Rails 3.2 with ActiveRecord and MySQL and I have models with one to many association:

class Author
  has_many :books
end

class Book
  belongs_to :author
  attr_accessible :review
end

I want to find authors that have all the books without review. I tried:

Author.includes(:books).where('book.review IS NIL')

but is obviously didn't work, because it finds authors that have at least one book without review. What query should I use?


回答1:


SQL is quite simple:

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

Translating it to the AR query language may take me some time... OK, so it seems to look like this:

Author.count('books.review', joins: :books, select: 'name', 
              group:'name', having: 'count_books_review=0')

As for me SQL looks much less weird then this ;-)




回答2:


Basing on the WRz answer I prepared my own query:

Author.joins(:books).group('authors.id').having("count(books.reviews)=0")

It's better suited for me, because it returns an AR Relation (and WRz's query returns a Hash).




回答3:


Try this

Author.joins(:books).where('books.review is null')

edit: This will fetch all the authors with at least one book with no review. I just realized your question is a bit different.

It would be something like this.

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)

P.S: This is not the exact syntax and it is untested




回答4:


Try the following code.

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!

After this code, authors will be an array containing all the authors having all the books unreviewed. Also note that I changed the author association in Book model to belongs_to instead of has_one. It is always a good practice to have has_many relation on one side and belongs_to association on the other side.



来源:https://stackoverflow.com/questions/15659503/query-has-many-where-all-the-child-fields-are-nil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!