Class: ActiveRecord::Associations::Preloader::ThroughAssociation

Inherits:
Association
  • Object
show all
Defined in:
lib/active_record/associations/preloader/through_association.rb

Overview

:nodoc:

Instance Attribute Summary

Attributes inherited from Association

#preloaded_records

Instance Method Summary collapse

Methods inherited from Association

#initialize

Constructor Details

This class inherits a constructor from ActiveRecord::Associations::Preloader::Association

Instance Method Details

#run(preloader) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/active_record/associations/preloader/through_association.rb', line 7

def run(preloader)
  already_loaded     = owners.first.association(through_reflection.name).loaded?
  through_scope      = through_scope()
  reflection_scope   = target_reflection_scope
  through_preloaders = preloader.preload(owners, through_reflection.name, through_scope)
  middle_records     = through_preloaders.flat_map(&:preloaded_records)
  preloaders         = preloader.preload(middle_records, source_reflection.name, reflection_scope)
  @preloaded_records = preloaders.flat_map(&:preloaded_records)

  owners.each do |owner|
    through_records = Array(owner.association(through_reflection.name).target)
    if already_loaded
      if source_type = reflection.options[:source_type]
        through_records = through_records.select do |record|
          record[reflection.foreign_type] == source_type
        end
      end
    else
      owner.association(through_reflection.name).reset if through_scope
    end
    result = through_records.flat_map do |record|
      association = record.association(source_reflection.name)
      target = association.target
      association.reset if preload_scope
      target
    end
    result.compact!
    if reflection_scope
      result.sort_by! { |rhs| preload_index[rhs] } if reflection_scope.order_values.any?
      result.uniq! if reflection_scope.distinct_value
    end
    associate_records_to_owner(owner, result)
  end
end