Reputation: 8030
I'll try explain my doubt starting from the beginning. I have the following tables:
carts
+----+-------------------------+-------------------------+
| id | created_at | updated_at |
+----+-------------------------+-------------------------+
| 1 | 2013-11-09 12:57:37 UTC | 2013-11-09 12:57:37 UTC |
| 2 | 2013-11-10 11:33:25 UTC | 2013-11-10 11:33:25 UTC |
| 3 | 2013-11-10 12:16:25 UTC | 2013-11-10 12:16:25 UTC |
+----+-------------------------+-------------------------+
line_items
+----+------------+---------+-------------------------+-------------------------+----------+
| id | product_id | cart_id | created_at | updated_at | quantity |
+----+------------+---------+-------------------------+-------------------------+----------+
| 1 | 2 | 2 | 2013-11-10 11:33:25 UTC | 2013-11-10 11:33:25 UTC | 1 |
| 2 | 2 | 2 | 2013-11-10 11:45:26 UTC | 2013-11-10 11:45:26 UTC | 1 |
| 3 | 5 | 2 | 2013-11-10 11:46:06 UTC | 2013-11-10 11:46:06 UTC | 1 |
| 4 | 2 | 2 | 2013-11-10 12:08:41 UTC | 2013-11-10 12:08:41 UTC | 1 |
| 5 | 5 | 2 | 2013-11-10 12:09:03 UTC | 2013-11-10 12:09:03 UTC | 1 |
| 6 | 5 | 2 | 2013-11-10 12:15:48 UTC | 2013-11-10 12:15:48 UTC | 1 |
| 7 | 2 | 3 | 2013-11-10 12:16:26 UTC | 2013-11-10 12:16:26 UTC | 1 |
| 8 | 2 | 3 | 2013-11-10 12:29:21 UTC | 2013-11-10 12:29:21 UTC | 1 |
+----+------------+---------+-------------------------+-------------------------+----------+
I execute the following statements:
cart = Cart.find(2)
sums = cart.line_items.group(:product_id).sum(:quantity)
The result is the following: => {2=>3, 5=>3}
Untill here I have to say that it seemed to me pretty clear, that is I calculate the sums of the products based on the product id and then I collapse same products.
The doubts came later, when I tried to break up the instruction cart.line_items.group(:product_id).sum(:quantity)
I followed the following steps:
cart = Cart.find(2)
items = cart.line_items.group(:product_id)
and I got:
+----+------------+---------+-------------------------+-------------------------+----------+
| id | product_id | cart_id | created_at | updated_at | quantity |
+----+------------+---------+-------------------------+-------------------------+----------+
| 4 | 2 | 2 | 2013-11-10 12:08:41 UTC | 2013-11-10 12:08:41 UTC | 1 |
| 6 | 5 | 2 | 2013-11-10 12:15:48 UTC | 2013-11-10 12:15:48 UTC | 1 |
+----+------------+---------+-------------------------+-------------------------+----------+
and finally I executed items.sum(:quantity)
and here, with my surprise, I got again=> {2=>3, 5=>3}
I came in doubt because I can't understand how I could get for each product id a number of quantity equals to 3 if I executed my sum
on an object (items
) which contains only 2 rows and for each one the quantity is 1.
What does items
memorize? The object obtained from cart.line_items.group(:product_id)
or and SQL string which means that everytime I interact with items
I interact with my database? I am getting a lit bit confused.
Upvotes: 1
Views: 60
Reputation: 29389
Good questions. :-)
items
is an ActiveRecord::Relation
which represents a query. Not all operations on that object result in another database operation, but some do. For example, length
and to_a
do not access the database again, but count
does.
Relations are also "chainable", so when you call items.sum(:quantity)
it builds a new relation. In other words, a relation can be thought of both as a query and the results from executing that query. When you chain methods, you're really operating on the query component, not the intermediate results.
Upvotes: 3