I found one answer that had some usable having
examples for finding parents with n
children, but the same is not usable for finding parents with no children (presumably since the join excludes them).
scope :with_children, joins(:children).group("child_join_table.parent_id").having("count(child_join_table.parent_id) > 0")
Can anyone point me in the right direction?
This should do the job you want:
Rails 3 & 4
The big difference here is the
joins
becoming aincludes
: an include loads all the relations, if they exists, the join will load only the associated objects and ignore the object without a relation.In fact,
scope :with_children, joins(:children)
should be just enough to return the Parent with at least 1 child. Try it out!Rails 5
As @MauroDias pointed out, if it is a self-referential relationship between your parent and children, this code above won't work.
With a little bit of research, I found out how to do it:
Consider this model:
How to return all items with no child(ren):
How did I find that
children_items
table?Item.joins(:children)
generates the following SQL:So I guessed that Rails uses a table when in need of a JOIN in a self-referential case.
Similar questions:
This is how I solved it for Rails 5:
@MrYoshiji has a solid Rails 4 answer, but for folks coming here with Rails 5 you have more options.
Using Rails 5:
As of Rails 5, you can also use left_outer_joins to avoid loading the association. It was introduced in pull request #12071.
For parents with children, MrYoshiji's Rails 4 solution is still the one to use: