1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Call run after preloading records

Ref: https://github.com/rails/rails/pull/41385

Otherwise the association isn't marked as loaded, and a ThroughAssociation
might perform the same query uselessly.

`already_loaded?` also has to be made lazy, because #41285
made it so that alls the preloaders are instiated together before being ran.
This commit is contained in:
Jean Boussier 2021-02-19 10:57:45 +01:00
parent ee7cf8cf75
commit 6074c59757
3 changed files with 35 additions and 7 deletions

View file

@ -103,7 +103,7 @@ module ActiveRecord
loaders = build_preloaders
group_and_load_similar(loaders)
loaders.map(&:run)
loaders.each(&:run)
child_preloaders.each { |reflection, child, parents| build_child_preloader(reflection, child, parents) }

View file

@ -11,7 +11,10 @@ module ActiveRecord
loaders.each { |l| l.set_inverse(record) }
end
loaders.each { |l| l.load_records(raw_records) }
loaders.each do |loader|
loader.load_records(raw_records)
loader.run
end
end
def initialize(klass, owners, reflection, preload_scope, associate_by_default = true)
@ -21,16 +24,14 @@ module ActiveRecord
@preload_scope = preload_scope
@associate = associate_by_default || !preload_scope || preload_scope.empty_scope?
@model = owners.first && owners.first.class
@already_loaded = owners.all? { |o| o.association(reflection.name).loaded? }
end
def already_loaded?
@already_loaded
@already_loaded ||= owners.all? { |o| o.association(reflection.name).loaded? }
end
def run
if @already_loaded
if already_loaded?
fetch_from_preloaded_records
return self
end

View file

@ -30,7 +30,8 @@ require "models/price_estimate"
class AssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
:computers, :people, :readers, :authors, :author_addresses, :author_favorites
:computers, :people, :readers, :authors, :author_addresses, :author_favorites,
:comments, :posts
def test_eager_loading_should_not_change_count_of_children
liquid = Liquid.create(name: "salty")
@ -407,12 +408,30 @@ class PreloaderTest < ActiveRecord::TestCase
assert_queries(1) do
preloader = ActiveRecord::Associations::Preloader.new(records: [book, post], associations: :author)
preloader.call
end
assert_no_queries do
book.author
post.author
end
end
def test_preload_through
comments = [
comments(:eager_sti_on_associations_s_comment1),
comments(:eager_sti_on_associations_s_comment2),
]
assert_queries(2) do
preloader = ActiveRecord::Associations::Preloader.new(records: comments, associations: [:author, :post])
preloader.call
end
assert_no_queries do
comments.each(&:author)
end
end
def test_preload_with_grouping_sets_inverse_association
mary = authors(:mary)
bob = authors(:bob)
@ -423,7 +442,9 @@ class PreloaderTest < ActiveRecord::TestCase
assert_queries(1) do
preloader = ActiveRecord::Associations::Preloader.new(records: favorites, associations: [:author, :favorite_author])
preloader.call
end
assert_no_queries do
favorites.first.author
favorites.first.favorite_author
end
@ -440,7 +461,9 @@ class PreloaderTest < ActiveRecord::TestCase
assert_queries(2) do
preloader = ActiveRecord::Associations::Preloader.new(records: [post, postesque], associations: :author_with_the_letter_a)
preloader.call
end
assert_no_queries do
post.author_with_the_letter_a
postesque.author_with_the_letter_a
end
@ -452,7 +475,9 @@ class PreloaderTest < ActiveRecord::TestCase
assert_queries(3) do
preloader = ActiveRecord::Associations::Preloader.new(records: [post, postesque], associations: :author_with_address)
preloader.call
end
assert_no_queries do
post.author_with_address
postesque.author_with_address
end
@ -466,7 +491,9 @@ class PreloaderTest < ActiveRecord::TestCase
assert_queries(2) do
preloader = ActiveRecord::Associations::Preloader.new(records: [post, postesque], associations: :author)
preloader.call
end
assert_no_queries do
post.author
postesque.author
end