我有一个多态关联(belongs_to :resource, polymorphic: true
) where resource
可以是多种不同的型号。为了简化问题,假设它可以是Order
or a Customer
.
如果它是一个Order
我想预加载订单,并预加载Address
。如果是客户我想预加载Customer
并预加载Location
.
使用这些关联的代码执行以下操作:
<%- @issues.each do |issue| -%>
<%- case issue.resource -%>
<%- when Customer -%>
<%= issue.resource.name %> <%= issue.resource.location.name %>
<%- when Order -%>
<%= issue.resource.number %> <%= issue.resource.address.details %>
<%- end -%>
目前我的预载使用:
@issues.preload(:resource)
然而,我仍然看到加载条件关联的 n 加一问题:
SELECT "addresses".* WHERE "addresses"."order_id" = ...
SELECT "locations".* WHERE "locations"."customer_id" = ...
...
有什么好方法来解决这个问题?是否可以手动预加载关联?
你可以在以下的帮助下做到这一点ActiveRecord::Associations::Preloader
班级。这是代码:
@issues = Issue.all # Or whatever query
ActiveRecord::Associations::Preloader.new.preload(@issues.select { |i| i.resource_type == "Order" }, { resource: :address })
ActiveRecord::Associations::Preloader.new.preload(@issues.select { |i| i.resource_type == "Customer" }, { resource: :location })
过滤集合时可以使用不同的方法。例如,在我的项目中我使用group_by
groups = sale_items.group_by(&:item_type)
groups.each do |type, items|
conditions = case type
when "Product" then :item
when "Service" then { item: { service: [:group] } }
end
ActiveRecord::Associations::Preloader.new.preload(items, conditions)
您可以轻松地将此代码包装在某个帮助程序类中,并在应用程序的不同部分中使用它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)