gpt4 book ai didi

sql - rails eager load has_many 通过连接表

转载 作者:行者123 更新时间:2023-12-01 13:52:01 25 4
gpt4 key购买 nike

我的开发环境是Rails 4.1和postgresql

我有 3 个具有 has_many 关系的模型:

class Item < ActiveRecord::Base
has_many :item_parts
has_many :parts, through: :item_parts
end

class Part < ActiveRecord::Base
has_many :item_parts
has_many :items, through: :item_parts
end

class ItemPart < ActiveRecord::Base
belongs_to :item
belongs_to :part
end

item_parts 连接表有一个 unit_count 属性来跟踪项目包含多少部分。

当我在 View 中遍历特定项目的所有部分时,我还需要从连接表中获取 unit_count 值。

这给了我 n+1 查询问题。

我试图预先加载连接表:

item.parts.includes(:item_parts)

ItemPart Load (0.5ms) SELECT "item_parts".* FROM "item_parts" WHERE "item_parts"."part_id" IN (24, 12, 3, 26)

但是当我这样做之后:

part.item_parts.where(item_id: item.id).first.unit_count

我得到了每个部分的以下 sql 查询;预加载不起作用

ItemPart Load (0.5ms)  SELECT "item_parts".* FROM "item_parts" WHERE "item_parts"."part_id" = $1 AND "item_parts"."item_id" = $2  [["part_id", 24], ["item_id", 18]]

有什么建议吗?

最佳答案

通过此链接,我找到了适合我的案例的解决方案:Rails Eager Loading and where clause

我不知道 Active Record 查询方法:选择 ( http://apidock.com/rails/v4.1.8/ActiveRecord/QueryMethods/select )

似乎我无法预先加载连接表,因为在包含 item_parts 之后,我在项目部分的迭代期间使用了 where 子句。

似乎在迭代期间每次使用 where 子句时都会对数据库进行新查询。

相反,select 方法不会每次都访问数据库,而是对加载到内存中的 Active Record 集合起作用。

所以我改变了这个:

item.parts.includes(:item_parts)
part.item_parts.where(item_id: item.id).first.unit_count

用这个:

item.parts.includes(:item_parts)
part.item_parts.select{|item_part| item_part.item_id == item.id}.first.unit_count

然后我有一个查询来加载 item_parts:

ItemPart Load (0.5ms)  SELECT "item_parts".* FROM "item_parts" WHERE "item_parts"."part_id" IN (24, 12, 3, 26)

关于sql - rails eager load has_many 通过连接表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30999963/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com