class EagerGroup::Preloader

Public Class Methods

new(klass, records, eager_group_values) click to toggle source
# File lib/eager_group/preloader.rb, line 11
def initialize(klass, records, eager_group_values)
  @klass = klass
  @records = Array.wrap(records).compact.uniq
  @eager_group_values = eager_group_values
end

Public Instance Methods

find_aggregate_values_per_definition!(definition_key, arguments) click to toggle source
# File lib/eager_group/preloader.rb, line 39
def find_aggregate_values_per_definition!(definition_key, arguments)
  unless definition = @klass.eager_group_definitions[definition_key]
    return
  end

  reflection = @klass.reflect_on_association(definition.association)
  return if reflection.blank?

  aggregation_finder_class = if reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
    ManyToMany
  elsif reflection.through_reflection
    if reflection.through_reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection)
      HasManyThroughBelongsTo
    else
      HasManyThroughMany
    end
  else
    HasMany
  end

  aggregation_finder = aggregation_finder_class.new(@klass, definition, arguments, @records)
  aggregate_hash = aggregation_finder.aggregate_hash

  if definition.need_load_object
    aggregate_objects = reflection.klass.find(aggregate_hash.values).each_with_object({}) { |o, h| h[o.id] = o }
    aggregate_hash.keys.each { |key| aggregate_hash[key] = aggregate_objects[aggregate_hash[key]] }
  end

  @records.each do |record|
    id = record.send(aggregation_finder.group_by_key)
    record.send("#{definition_key}=", aggregate_hash[id] || definition.default_value)
  end
end
run() click to toggle source

Preload aggregate functions

# File lib/eager_group/preloader.rb, line 18
def run
  @eager_group_values.each do |eager_group_value|
    definition_key, arguments =
      eager_group_value.is_a?(Array) ? [eager_group_value.shift, eager_group_value] : [eager_group_value, nil]

    if definition_key.is_a?(Hash)
      association_name, definition_key = *definition_key.first
      next if @records.empty?
      @klass = @records.first.class.reflect_on_association(association_name).klass

      @records = @records.flat_map { |record| record.send(association_name) }
      next if @records.empty?


      self.class.new(@klass, @records, Array.wrap(definition_key)).run
    end

    find_aggregate_values_per_definition!(definition_key, arguments)
  end
end

Private Instance Methods

polymophic_as_condition(reflection) click to toggle source
# File lib/eager_group/preloader.rb, line 75
def polymophic_as_condition(reflection)
  reflection.type ? { reflection.name => { reflection.type => @klass.base_class.name } } : []
end