I'd like to trigger eager loading on a relation with an #includes
call, that was modified with a custom preloader using ActiveRecord::Associations::Preloader
on a Rails 7 app, Ruby 3.2:
class Product < ApplicationRecord
belongs_to :vendor
has_many :taxons
end
class Vendor < ApplicationRecord
has_many :products
end
records = Product.where(id: [1,2,3,4])
scope = Vendor.where.not(id: [5,6])
preloader = ActiveRecord::Associations::Preloader.new(records:, associations: :vendor, scope:).tap(&:call)
puts records.first.association_cached?(:vendor)
=> true
puts records.includes(:taxons).first.association_cached?(:vendor)
=> false
I need the scope:
argument because some users aren't allowed to access certain resources.
Without the includes(:taxons)
call, the association :vendor
is correctly eager loaded and cached. But in the second case, it seems like the whole eager loading of Preloader
is somehow dropped.
Is there a way to include a custom preloader as a chain argument along with other includes
? I get an error when I try to include the preloader itself like this:
records.includes(preloader).to_a
ActiveRecord::AssociationNotFoundError: Association named '#<ActiveRecord::Associations::Preloader:0x00007f573bc31ab0>' was not found on Product; perhaps you misspelled it?
from /usr/local/bundle/gems/activerecord-7.0.4.2/lib/active_record/associations.rb:302:in `association'