aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb21
-rw-r--r--activerecord/lib/active_record/reflection.rb2
2 files changed, 12 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb
index 3166df57eb..2a8530af62 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -29,29 +29,30 @@ module ActiveRecord
source_reflection.name,
reflection_scope)
+ @preloaded_records = preloaders.flat_map(&:preloaded_records)
+
middle_to_pl = preloaders.each_with_object({}) do |pl,h|
pl.owners.each { |middle|
h[middle] = pl
}
end
+ record_offset = {}
+ @preloaded_records.each_with_index do |record,i|
+ record_offset[record] = i
+ end
+
through_records.each_with_object({}) { |(lhs,center),records_by_owner|
pl_to_middle = center.group_by { |record| middle_to_pl[record] }
records_by_owner[lhs] = pl_to_middle.flat_map do |pl, middles|
rhs_records = middles.flat_map { |r|
- r.send(source_reflection.name)
+ association = r.association source_reflection.name
+
+ association.reader
}.compact
- loaded_records = pl.preloaded_records
- i = 0
- record_index = loaded_records.each_with_object({}) { |r,indexes|
- indexes[r] = i
- i += 1
- }
- records = rhs_records.sort_by { |rhs| record_index[rhs] }
- @preloaded_records.concat rhs_records
- records
+ rhs_records.sort_by { |rhs| record_offset[rhs] }
end
}
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index e88c5d17cb..bce7766501 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -574,7 +574,7 @@ module ActiveRecord
# Add to it the scope from this reflection (if any)
scope_chain.first << scope if scope
- through_scope_chain = through_reflection.scope_chain
+ through_scope_chain = through_reflection.scope_chain.map(&:dup)
if options[:source_type]
through_scope_chain.first <<