diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2017-10-30 23:55:48 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2017-11-06 05:52:52 +0900 |
commit | e617fb57f5a388d5f0a47fd5e576588dd10066b0 (patch) | |
tree | 4225fe0bfa8bb3680852c624d42f0bcca522a831 /activerecord/lib/active_record | |
parent | 8a2ee3d8c6921ce34e597658e3f2b43b41423d1d (diff) | |
download | rails-e617fb57f5a388d5f0a47fd5e576588dd10066b0.tar.gz rails-e617fb57f5a388d5f0a47fd5e576588dd10066b0.tar.bz2 rails-e617fb57f5a388d5f0a47fd5e576588dd10066b0.zip |
Fix preloading polymorphic association when through association has already loaded
If through association has already loaded, `source_type` is ignored to
loaded through records. The loaded records should be filtered by
`source_type` in that case.
Fixes #30904.
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/associations/preloader/through_association.rb | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb index fa32cc5553..5bd49b041a 100644 --- a/activerecord/lib/active_record/associations/preloader/through_association.rb +++ b/activerecord/lib/active_record/associations/preloader/through_association.rb @@ -13,18 +13,30 @@ module ActiveRecord end def associated_records_by_owner(preloader) + already_loaded = owners.first.association(through_reflection.name).loaded? through_scope = through_scope() - preloader.preload(owners, - through_reflection.name, - through_scope) + unless already_loaded + preloader.preload(owners, through_reflection.name, through_scope) + end through_records = owners.map do |owner| center = owner.association(through_reflection.name).target [owner, Array(center)] end - reset_association(owners, through_reflection.name, through_scope) + if already_loaded + if source_type = reflection.options[:source_type] + through_records.map! do |owner, center| + center = center.select do |record| + record[reflection.foreign_type] == source_type + end + [owner, center] + end + end + else + reset_association(owners, through_reflection.name, through_scope) + end middle_records = through_records.flat_map(&:last) |