diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2016-02-29 11:17:25 -0700 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2016-02-29 11:20:43 -0700 |
commit | 67aa8f194331d7b19b47eb80b71bff027df8684f (patch) | |
tree | 773065bc1f82ce64f51e5631d20bcd5d3333bd59 /activerecord/lib/active_record/associations | |
parent | 1d3502c32e5553d3e9e73cb7d38db0c1d6427aaf (diff) | |
parent | 524238139025ccddfa886bcfd7a1a6434954e305 (diff) | |
download | rails-67aa8f194331d7b19b47eb80b71bff027df8684f.tar.gz rails-67aa8f194331d7b19b47eb80b71bff027df8684f.tar.bz2 rails-67aa8f194331d7b19b47eb80b71bff027df8684f.zip |
Merge pull request #18766 from yasyf/issue_17864
Honour joining model order in `has_many :through` associations when
eager loading
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r-- | activerecord/lib/active_record/associations/preloader/through_association.rb | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb index 6c83058202..b0203909ce 100644 --- a/activerecord/lib/active_record/associations/preloader/through_association.rb +++ b/activerecord/lib/active_record/associations/preloader/through_association.rb @@ -38,12 +38,7 @@ module ActiveRecord } 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| + through_records.each_with_object({}) do |(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| @@ -53,13 +48,25 @@ module ActiveRecord target_records_from_association(association) }.compact - rhs_records.sort_by { |rhs| record_offset[rhs] } + # Respect the order on `reflection_scope` if it exists, else use the natural order. + if reflection_scope.values[:order].present? + @id_map ||= id_to_index_map @preloaded_records + rhs_records.sort_by { |rhs| @id_map[rhs] } + else + rhs_records + end end - } + end end private + def id_to_index_map(ids) + id_map = {} + ids.each_with_index { |id, index| id_map[id] = index } + id_map + end + def reset_association(owners, association_name) should_reset = (through_scope != through_reflection.klass.unscoped) || (reflection.options[:source_type] && through_reflection.collection?) |