class ActiveRecord::Associations::Preloader

Public Instance Methods

display_virtual_attribute_deprecation(str) click to toggle source

rubocop:enable Style/BlockDelimiters, Lint/AmbiguousBlockAssociation, Style/MethodCallWithArgsParentheses

# File lib/active_record/virtual_attributes/virtual_fields.rb, line 208
def display_virtual_attribute_deprecation(str)
  short_caller = caller
  # if debugging is turned on, don't prune the backtrace.
  # if debugging is off, prune down to the line where the sql is executed
  # this defaults to false and only displays 1 line number.
  unless ActiveSupport::Deprecation.debug
    bc = ActiveSupport::BacktraceCleaner.new
    bc.add_silencer { |line| line =~ /virtual_fields/ }
    bc.add_silencer { |line| line =~ /active_record/ }
    short_caller = bc.clean(caller)
  end

  ActiveSupport::Deprecation.warn(str, short_caller)
end
grouped_records(orig_association, records, polymorphic_parent) click to toggle source

preloader.rb active record 6.0 changed: different from 5.2. But not called outside these redefined methods here, so it works fine did add compact to fix a 5.2 double preload nil bug

# File lib/active_record/virtual_attributes/virtual_fields.rb, line 183
def grouped_records(orig_association, records, polymorphic_parent)
  h = {}
  records.compact.each do |record|
    # each class can resolve virtual_{attributes,includes} differently
    association = record.class.replace_virtual_fields(orig_association)
    # 1 line optimization for single element array:
    association = association.first if association.kind_of?(Array) && association.size == 1

    case association
    when Symbol, String
      # 4/24/20 we want to revert #67 once we handle all these error cases in our codebase.
      reflection = record.class._reflect_on_association(association)
      display_virtual_attribute_deprecation("#{record.class.name}.#{association} does not exist") if !reflection && !polymorphic_parent
      next if !reflection || !record.association(association).klass
    when nil
      next
    else # need parent (preloaders_for_{hash,one}) to handle this Array/Hash
      reflection = association
    end
    (h[reflection] ||= []) << record
  end
  h
end
preloaders_for_hash(association, records, scope, polymorphic_parent) click to toggle source

rubocop:disable Style/BlockDelimiters, Lint/AmbiguousBlockAssociation, Style/MethodCallWithArgsParentheses preloader.rb active record 6.0 changed: passing polymorphic around (and makes 5.2 more similar to 6.0)

# File lib/active_record/virtual_attributes/virtual_fields.rb, line 155
def preloaders_for_hash(association, records, scope, polymorphic_parent)
  association.flat_map { |parent, child|
    grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records|
      loaders = preloaders_for_reflection(reflection, reflection_records, scope, polymorphic_parent)
      recs = loaders.flat_map(&:preloaded_records).uniq
      child_polymorphic_parent = reflection && reflection.respond_to?(:options) && reflection.options[:polymorphic]
      loaders.concat Array.wrap(child).flat_map { |assoc|
        preloaders_on assoc, recs, scope, child_polymorphic_parent
      }
      loaders
    end
  }
end
preloaders_for_one(association, records, scope, polymorphic_parent) click to toggle source

preloader.rb active record 6.0 changed: passing polymorphic_parent to preloaders_for_reflection

# File lib/active_record/virtual_attributes/virtual_fields.rb, line 172
def preloaders_for_one(association, records, scope, polymorphic_parent)
  grouped_records(association, records, polymorphic_parent)
    .flat_map do |reflection, reflection_records|
      preloaders_for_reflection(reflection, reflection_records, scope, polymorphic_parent)
    end
end
preloaders_for_reflection(reflection, records, scope, polymorphic_parent) click to toggle source

preloader.rb active record 6.0 changed: since grouped_records can return a hash/array, we need to handle those 2 new cases

Calls superclass method
# File lib/active_record/virtual_attributes/virtual_fields.rb, line 108
def preloaders_for_reflection(reflection, records, scope, polymorphic_parent)
  case reflection
  when Array
    reflection.flat_map { |ref| preloaders_on(ref, records, scope, polymorphic_parent) }
  when Hash
    preloaders_on(reflection, records, scope, polymorphic_parent)
  else
    super(reflection, records, scope)
  end
end
preloaders_on(association, records, scope, polymorphic_parent = false) click to toggle source

preloader.rb active record 6.0 since this deals with polymorphic_parent, it makes everything easier to just define it

# File lib/active_record/virtual_attributes/virtual_fields.rb, line 138
def preloaders_on(association, records, scope, polymorphic_parent = false)
  case association
  when Hash
    preloaders_for_hash(association, records, scope, polymorphic_parent)
  when Symbol, String
    preloaders_for_one(association.to_sym, records, scope, polymorphic_parent)
  else
    raise ArgumentError, "#{association.inspect} was not recognized for preload"
  end
end