[英]rails eager load has_many through join table
我的開發環境是 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 屬性來跟蹤項目包含的部分數量。
當我在視圖中遍歷特定項目的所有部分時,我還需要從連接表中獲取 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 和 where 子句
我不知道 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 查詢”
嘗試改用.length或.size方法。
注:(引用文章)
再次查看后,我不確定您為什么要將計數添加到連接表中。
@items = Item.includes(:parts)
@items.each do |item|
parts_count_per_item = item.parts.size
end
或者
@parts = Part.includes(:items)
@parts.each do |part|
items_count_per_part = part.items.size
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.