aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorTomohito Ozaki <ozaki@yuroyoro.com>2015-03-06 11:55:22 +0900
committerTomohito Ozaki <ozaki@yuroyoro.com>2015-04-17 11:20:46 +0900
commit842f5c2dad8ed021274c16f2dc231c15ddefba18 (patch)
tree6af333d0b761ba5e512bcbbd24b0e4eadf6f5c25 /activerecord
parenta1d042bea1d3b6d2e41356b3240e3e146823c19b (diff)
downloadrails-842f5c2dad8ed021274c16f2dc231c15ddefba18.tar.gz
rails-842f5c2dad8ed021274c16f2dc231c15ddefba18.tar.bz2
rails-842f5c2dad8ed021274c16f2dc231c15ddefba18.zip
Read already loaded association records from association.target
For performance, Avoid instantiate CollectionProxy. Fixes #12537
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 56aa23b173..d9cd90db1a 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] }
@@ -89,6 +90,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 7d8b933992..2c6f199cf1 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -1349,4 +1349,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