diff --git a/activerecord/lib/active_record/associations/preloader.rb b/activerecord/lib/active_record/associations/preloader.rb index 274a3352fce8f8f955df72aa6b1a0371b59bd45c..3ca07498c590e9de03669f07d2d960a86d5abb9d 100644 --- a/activerecord/lib/active_record/associations/preloader.rb +++ b/activerecord/lib/active_record/associations/preloader.rb @@ -86,24 +86,29 @@ def initialize(records, associations, preload_scope = nil) @records = Array.wrap(records).compact.uniq @associations = Array.wrap(associations) @preload_scope = preload_scope || NULL_RELATION + @preloaders = nil end NULL_RELATION = Struct.new(:values).new({}) def run - run_preload associations, records + preloaders.each(&:run) end - private + def preloaders + return @preloaders if @preloaders - def run_preload(associations, records) - unless records.empty? - associations.flat_map { |association| + if records.empty? + @preloaders = [] + else + @preloaders = associations.flat_map { |association| preload(association, records) - }.each(&:run) + } end end + private + def preload(association, records) case association when Hash @@ -123,12 +128,7 @@ def preloaders_for_hash(association, records) loaders = preloaders_for_one parent, records recs = loaders.flat_map(&:target_records).uniq - lls = Array.wrap(child).flat_map { |assoc| preload assoc, recs } - loaders + lls - end - - def preload_hash(association, records) - preloaders_for_hash(association, records).each(&:run) + loaders.concat Array.wrap(child).flat_map { |assoc| preload assoc, recs } end # Not all records have the same class, so group then preload group on the reflection