After googling, browsing SO and reading, there doesn\'t seem to be a Rails-style way to efficiently get only those Parent
objects which have at leas
try including the children with #includes()
Parent.includes(:children).all.reject { |parent| parent.children.empty? }
This will make 2 queries:
SELECT * FROM parents;
SELECT * FROM children WHERE parent_id IN (5, 6, 8, ...);
[UPDATE]
The above solution is usefull when you need to have the Child objects loaded.
But children.empty?
can also use a counter cache1,2 to determine the amount of children.
For this to work you need to add a new column to the parents
table:
# a new migration
def up
change_table :parents do |t|
t.integer :children_count, :default => 0
end
Parent.reset_column_information
Parent.all.each do |p|
Parent.update_counters p.id, :children_count => p.children.length
end
end
def down
change_table :parents do |t|
t.remove :children_count
end
end
Now change your Child
model:
class Child
belongs_to :parent, :counter_cache => true
end
At this point you can use size
and empty?
without touching the children
table:
Parent.all.reject { |parent| parent.children.empty? }
Note that length
doesn't use the counter cache whereas size
and empty?
do.