aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-12-18 18:46:14 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2015-12-18 18:46:14 -0800
commit914a45b5fef39c436322bca02566d0d11e1cbb84 (patch)
tree47b4989d09029dc0610a6ec878e928c786ce8911 /activerecord
parenta81f73a506a44b39420b9007f4ca3c017c1e74f8 (diff)
parent842f5c2dad8ed021274c16f2dc231c15ddefba18 (diff)
downloadrails-914a45b5fef39c436322bca02566d0d11e1cbb84.tar.gz
rails-914a45b5fef39c436322bca02566d0d11e1cbb84.tar.bz2
rails-914a45b5fef39c436322bca02566d0d11e1cbb84.zip
Merge pull request #19423 from yuroyoro/fix_performance_regression_of_preloading_has_many_through_relation
Fix #12537 performance regression when preloading has_many_through association
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb9
-rw-r--r--activerecord/test/cases/associations/eager_test.rb6
2 files changed, 13 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb
index 24aa47bb51..6c83058202 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -18,7 +18,8 @@ module ActiveRecord
through_records = owners.map do |owner|
association = owner.association through_reflection.name
- [owner, Array(association.reader)]
+ center = target_records_from_association(association)
+ [owner, Array(center)]
end
reset_association owners, through_reflection.name
@@ -49,7 +50,7 @@ module ActiveRecord
rhs_records = middles.flat_map { |r|
association = r.association source_reflection.name
- association.reader
+ target_records_from_association(association)
}.compact
rhs_records.sort_by { |rhs| record_offset[rhs] }
@@ -91,6 +92,10 @@ module ActiveRecord
scope
end
+
+ def target_records_from_association(association)
+ association.loaded? ? association.target : association.reader
+ end
end
end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 0c09713971..874d53c51f 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1402,4 +1402,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
post = Post.eager_load(:tags).where('tags.name = ?', 'General').first
assert_equal posts(:welcome), post
end
+
+ # CollectionProxy#reader is expensive, so the preloader avoids calling it.
+ test "preloading has_many_through association avoids calling association.reader" do
+ ActiveRecord::Associations::HasManyAssociation.any_instance.expects(:reader).never
+ Author.preload(:readonly_comments).first!
+ end
end