Reputation: 51156
If I have a model of type Foo that has many child records of type Bar, I'd like to be able to show a list of Foo records and show the number of child Bar records. So I have something like...
@foos.each do |foo|
puts foo.name
puts foo.bars.count
end
How can I avoid the N+1 problem on my aggregates? In other words, I don't want a new SELECT COUNT(*)...
query for each row. I could simply create a SQL view and map it to a new Model, but is there a simpler approach?
Upvotes: 2
Views: 485
Reputation: 1813
DataMpper is fickle about these things so I'll give you a couple options to try that may work depending on what your real code looks like.
Just change count to size, i.e., puts foo.bars.size. DM's strategic eager loading can sometimes work with this approach.
Force an eager load before the @foos.each loop, and change count to size, e.g.
@foos = Foo.all(...)
@foos.bars.to_a
@foos.each do | foo |
puts foo.name
puts foo.bars.size
end
Issue a raw SQL query before your @foos.each loop that returns structs with foo ids and bar counts, #map those into a Hash by food id and get them inside the loop. (I've only had to resort to this level of nonsense once or twice, I'd recommend fiddling with #1 and 2 for bit before it.)
Upvotes: 1