Reputation: 5890
I am wondering how to do this without double each loop. Assume that I have a user model and order model, and user has_many orders.
Now I have a users array which class is User::ActiveRecord_Relation
How can I get the orders of these users in one line?
Upvotes: 0
Views: 34
Reputation: 211540
If you've got a many-to-many association and you need to quickly load in all the associated orders you will need to be careful to avoid the so-called "N plus 1" load that can result from the most obvious approach:
orders = users.collect(&:orders).flatten
This will iterate over each user and run a query like SELECT * FROM orders WHERE user_id=?
without any grouping.
What you really want is this:
orders = Order.where(user_id: users.collect(&:id))
That should find all orders from all users in a single query.
Upvotes: 1
Reputation: 4093
Actually, the best way to do that is :
users.includes(:orders).map(&:orders)
Cause you eager load the orders of the users (only 2 sql queries)
Or
Order.where(user_id: users.pluck(:id))
is quite good too in term of performance
Upvotes: 2
Reputation: 5890
An answer just come up my mind after I asked....
users.map {|user| user.orders}
Upvotes: 0