使用多态关联时如何避免n + 1个查询?

Rod*_*igo 12 activerecord ruby-on-rails

我有4个型号,让我们说:

class Photo < ActiveRecord::Base
  belongs_to :photoable, polymorphic: true
end

class User < ActiveRecord::Base
  has_one :photo, as: :photoable
end    

class Company < ActiveRecord::Base
  has_one :photo, as: :photoable
  has_many :products
end

class Products < ActiveRecord::Base
  belongs_to :company
end
Run Code Online (Sandbox Code Playgroud)

所以,查询Photo.all.includes(:photoable)工作.

但如果我Photo.all.includes(photoable: :products)只使用所有加载的照片属于公司的作品.如果关系包含用户和公司的照片,则会引发此错误:

ActiveRecord::ConfigurationError (Association named 'products' was not found; perhaps you misspelled it?):
Run Code Online (Sandbox Code Playgroud)

这是因为用户与产品没有关系.

有没有办法急切地加载用户和公司产品的照片关系?

编辑:

这个问题与Eager load polymorphic不重复.正如我在下面评论的那样,在这个问题中,我想对具有不同关联的多态关联做一个急切的加载(一个有产品而另一个没有).在该问题中,OP对表名使用了错误的名称.

pie*_*ard 0

我有同样的问题,并找到了解决方案。

您可以在 find 之后调用急切加载:

photos = Photo.all.includes(:photoable)
photos_with_products_association = photos.select{|p| p.photoable.is_a?(Company)}
ActiveRecord::Associations::Preloader.new.preload(
  photos_with_products_association,
  :products
)
Run Code Online (Sandbox Code Playgroud)

...或更通用

photos_with_products_association = photos.select do |p|
  p.class.reflections.keys.include?(:products)
end
Run Code Online (Sandbox Code Playgroud)