Sha256: 653bc1f271afc71653122b4fd31d34a171e3e8ac4558871addf7ace1a5866523

Contents?: true

Size: 1.94 KB

Versions: 1

Compression:

Stored size: 1.94 KB

Contents

# frozen_string_literal: true

require "ar_lazy_preload/associated_context_builder"

module ArLazyPreload
  # This class is responsible for holding a connection between a list of ActiveRecord::Base objects
  # which have been loaded by the same instance of ActiveRecord::Relation. It also contains a tree
  # of associations, which were requested to be loaded lazily.
  # Calling #preload_association method will cause loading of ALL associated objects for EACH
  # ecord when requested association is found in the association tree.
  class Context
    # Initiates lazy preload context for given records
    def self.register(records:, association_tree:)
      return if records.empty? || association_tree.empty?
      ArLazyPreload::Context.new(records: records, association_tree: association_tree)
    end

    attr_reader :records, :association_tree

    # :records - array of ActiveRecord instances
    # :association_tree - list of symbols or hashes representing a tree of preloadable associations
    def initialize(records:, association_tree:)
      @records = records.compact
      @association_tree = association_tree

      @records.each { |record| record.lazy_preload_context = self }
    end

    # This method checks if the association is present in the association_tree and preloads for all
    # objects in the context it if needed.
    def try_preload_lazily(association_name)
      return unless association_needs_preload?(association_name)
      preloader.preload(records, association_name)
      AssociatedContextBuilder.prepare(parent_context: self, association_name: association_name)
    end

    private

    def association_needs_preload?(association_name)
      association_tree.any? do |node|
        if node.is_a?(Symbol)
          node == association_name
        elsif node.is_a?(Hash)
          node.key?(association_name)
        end
      end
    end

    def preloader
      @preloader ||= ActiveRecord::Associations::Preloader.new
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
ar_lazy_preload-0.1.1 lib/ar_lazy_preload/context.rb