diff options
Diffstat (limited to 'activerecord/lib')
4 files changed, 60 insertions, 8 deletions
| diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index ade5946dd5..3cef92df5d 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -157,6 +157,14 @@ end_warning        end      end +    initializer "active_record.collection_cache_association_loading" do +      require "active_record/railties/collection_cache_association_loading" +      ActiveSupport.on_load(:action_view) do +        ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading) +      end +    end + +      initializer "active_record.set_reloader_hooks" do        ActiveSupport.on_load(:active_record) do          ActiveSupport::Reloader.before_class_unload do diff --git a/activerecord/lib/active_record/railties/collection_cache_association_loading.rb b/activerecord/lib/active_record/railties/collection_cache_association_loading.rb new file mode 100644 index 0000000000..b5129e4239 --- /dev/null +++ b/activerecord/lib/active_record/railties/collection_cache_association_loading.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module ActiveRecord +  module Railties # :nodoc: +    module CollectionCacheAssociationLoading #:nodoc: +      def setup(context, options, block) +        @relation = relation_from_options(options) + +        super +      end + +      def relation_from_options(cached: nil, partial: nil, collection: nil, **_) +        return unless cached + +        relation = partial if partial.is_a?(ActiveRecord::Relation) +        relation ||= collection if collection.is_a?(ActiveRecord::Relation) + +        if relation && !relation.loaded? +          relation.skip_preloading! +        end +      end + +      def collection_without_template +        @relation.preload_associations(@collection) if @relation +        super +      end + +      def collection_with_template +        @relation.preload_associations(@collection) if @relation +        super +      end +    end +  end +end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 736173ae1b..34e643b2de 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -8,7 +8,8 @@ module ActiveRecord                              :extending, :unscope]      SINGLE_VALUE_METHODS = [:limit, :offset, :lock, :readonly, :reordering, -                            :reverse_order, :distinct, :create_with, :skip_query_cache] +                            :reverse_order, :distinct, :create_with, :skip_query_cache, +                            :skip_preloading]      CLAUSE_METHODS = [:where, :having, :from]      INVALID_METHODS_FOR_DELETE_ALL = [:distinct, :group, :having] @@ -546,6 +547,16 @@ module ActiveRecord        ActiveRecord::Associations::AliasTracker.create(connection, table.name, joins)      end +    def preload_associations(records) +      preload = preload_values +      preload += includes_values unless eager_loading? +      preloader = nil +      preload.each do |associations| +        preloader ||= build_preloader +        preloader.preload records, associations +      end +    end +      protected        def load_records(records) @@ -575,13 +586,7 @@ module ActiveRecord                klass.find_by_sql(arel, &block).freeze              end -          preload = preload_values -          preload += includes_values unless eager_loading? -          preloader = nil -          preload.each do |associations| -            preloader ||= build_preloader -            preloader.preload @records, associations -          end +          preload_associations(@records) unless skip_preloading_value            @records.each(&:readonly!) if readonly_value diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 3afa368575..4e60863e52 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -899,6 +899,11 @@ module ActiveRecord        self      end +    def skip_preloading! # :nodoc: +      self.skip_preloading_value = true +      self +    end +      # Returns the Arel object associated with the relation.      def arel(aliases = nil) # :nodoc:        @arel ||= build_arel(aliases) | 
