Skip to content

Instantly share code, notes, and snippets.

@ssnickolay
Created December 19, 2019 12:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ssnickolay/f171ae9b4e71fd36686989ef7063bc89 to your computer and use it in GitHub Desktop.
Save ssnickolay/f171ae9b4e71fd36686989ef7063bc89 to your computer and use it in GitHub Desktop.
Preload with Rails 6+
def preload_association(records)
::ActiveRecord::Associations::Preloader.new.preload(
records,
@association_schema,
@preload_scope
).then(&:first).then do |preloader|
next unless @preload_scope
# The result of previous preload is memoized, ActiveRecord won't load this association again.
if preloader.is_a?(::ActiveRecord::Associations::Preloader::AlreadyLoaded)
owner = preloader.send(:owners).first
# We can use batch_load with the _one_ set of scopes many times during the request
raise ArgumentError,
"Preloading association twice with scopes is not possible. " \
"To resolve this problem add a scoped association (e.g., `has_many :records, -> { scope_name }, ...`) to the model"
end
# this commit changes the way preloader works with scopes
# https://github.com/rails/rails/commit/2847653869ffc1ff5139c46e520c72e26618c199#diff-3bba5f66eb1ed62bd5700872fcd6c632
preloader.send(:owners).each do |owner|
preloader.send(:associate_records_to_owner, owner, preloader.records_by_owner[owner] || [])
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment