【发布时间】:2014-04-16 23:25:23
【问题描述】:
如标题所述:如何使用 Rails 4 订购嵌套的 includes 记录?
以下是模型的概述:
产品
- 标题
- 价格
- 等
产品尺寸
- product_id
- size_id
尺寸
- 宽度
- 身高
- 订购
一个Product 有许多Sizes 到ProductSize。 Sizes 将通过order 订购Size 型号。我在 Sizes 模型上设置了 default_scope 或 order('order DESC')
我希望能够获得products 的列表,然后遍历每个product 并显示可用sizes 的列表,按size order 排序。我想要这一切而又不进行低效查询(n+1 问题),所以我使用includes。
为此,我运行Product.includes(:product_sizes => [:size]).all 生成:
SELECT "products".* FROM "products"
SELECT "product_sizes".* FROM "product_sizes"
WHERE "product_sizes"."product_id" IN (X, X, X, X)
SELECT "sizes".* FROM "sizes"
WHERE "sizes"."id" IN (X, X, X, X, X, X, X, X) ORDER BY `order` ASC
如您所见,我的订单将关闭,因为它将使用我从 product_sizes 查询中获取记录的顺序。您还可以注意到sizes 的查询确实有ORDER BY 语句,但它不影响最终结果。
我最初的想法是 size 应该只是 joined 到 product_size 查询。不幸的是,我不知道如何使用includes。
理想情况下,生成的查询看起来更像:
SELECT "products".* FROM "products"
SELECT "product_sizes".* FROM "product_sizes"
WHERE "product_sizes"."product_id" IN (X, X, X, X)
JOIN "size" ON product_sizes.size_id = sizes.id
ORDER BY `size`.`order`
SELECT "sizes".* FROM "sizes"
WHERE "sizes"."id" IN (X, X, X, X, X, X, X, X) ORDER BY `order` ASC
【问题讨论】:
-
加入
sizes会大大增加传输的数据量,因为product_sizes的列对于同一产品的每种尺寸都会重复。Product.preload(:product_sizes).first.sizes? -
不确定它是否有效,但疯狂猜测:
Product.preload(:product_sizes).eager_load(:product_sizes => :size),即使有效也不推荐。
标签: mysql ruby-on-rails ruby activerecord ruby-on-rails-4