Reputation: 56709
I need to do the following:
<% for customer in @customers do %>
<%= customer.orders.count %>
<% end %>
This strains the server, creating n queries, where n = number of customers.
How can I load these counts along with my customers in one query? Thanks.
Upvotes: 1
Views: 169
Reputation: 62638
You could use an eager join:
@customers = Customers.paginate :page => 1, :per_page => 20, :include => [:orders]
By specifying the :include parameter to the join, the orders will be preloaded, preventing the n+1 problem. You can then use customer.orders.length.
If loading all those orders is too memory-intensive, then you should explore counter_cache
. This is designed to keep a count of a model on an associated model:
class Order
belongs_to :customer, :counter_cache => true
end
This will increment and decrement a orders_count
field on the owning customer
record when orders are added or removed from the associaition.
If you don't want to use the counter_cache, you'll need custom finder SQL which joins the orders table and groups on orders.customer_id, and then selects the count as an extra field. This will not perform nearly as well as the counter cache, though.
Upvotes: 2