更深入地了解ActiveRecord

时间:2013-11-10 14:32:55

标签: ruby-on-rails activerecord

我会从头开始尝试解释我的疑问。我有以下表格:

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        |
+----+------------+---------+-------------------------+-------------------------+----------+

我执行以下陈述:

cart = Cart.find(2)
sums = cart.line_items.group(:product_id).sum(:quantity)

结果如下:=> {2=>3, 5=>3}
在这里,我不得不说,在我看来很清楚,那就是我根据产品ID计算产品的总和,然后我折叠相同的产品。 当我试图打破指令cart.line_items.group(:product_id).sum(:quantity)时,怀疑来得更晚了。
我按照以下步骤操作:

cart = Cart.find(2)
items = cart.line_items.group(:product_id)

我得到了:

+----+------------+---------+-------------------------+-------------------------+----------+
| 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        |
+----+------------+---------+-------------------------+-------------------------+----------+

最后我执行了items.sum(:quantity),在这里,我惊讶的是,我再次=> {2=>3, 5=>3}
我怀疑是因为如果我在包含对象(sum)的items上执行了items,我无法理解如何获取每个产品ID的数量等于3只有2行,每一行的数量为1。
cart.line_items.group(:product_id)记住了什么?从items或SQL字符串获取的对象,这意味着每次与{{1}}交互时,我都会与我的数据库进行交互?我有点困惑。

1 个答案:

答案 0 :(得分:3)

好问题。 : - )

itemsActiveRecord::Relation,代表查询。并非该对象上的所有操作都会导致其他数据库操作,但有些操作会导致。例如,lengthto_a不会再次访问数据库,但count会这样做。

关系也是“可链接的”,因此当您致电items.sum(:quantity)时,它会构建新的关系。换句话说,可以将关系视为查询和执行该查询的结果。当您链接方法时,您实际上是在查询组件上操作,而不是中间结果。