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

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

Overview

:nodoc:

Constant Summary collapse

PRELOADER =
ActiveRecord::Associations::Preloader.new(associate_by_default: false)

Instance Method Summary collapse

Methods inherited from Association

#run

Constructor Details

#initializeThroughAssociation

Returns a new instance of ThroughAssociation.



9
10
11
12
# File 'lib/active_record/associations/preloader/through_association.rb', line 9

def initialize(*)
  super
  @already_loaded = owners.first.association(through_reflection.name).loaded?
end

Instance Method Details

#preloaded_recordsObject



14
15
16
# File 'lib/active_record/associations/preloader/through_association.rb', line 14

def preloaded_records
  @preloaded_records ||= source_preloaders.flat_map(&:preloaded_records)
end

#records_by_ownerObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/active_record/associations/preloader/through_association.rb', line 18

def records_by_owner
  return @records_by_owner if defined?(@records_by_owner)
  source_records_by_owner = source_preloaders.map(&:records_by_owner).reduce(:merge)
  through_records_by_owner = through_preloaders.map(&:records_by_owner).reduce(:merge)

  @records_by_owner = owners.each_with_object({}) do |owner, result|
    through_records = through_records_by_owner[owner] || []

    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
    end

    records = through_records.flat_map do |record|
      source_records_by_owner[record]
    end

    records.compact!
    records.sort_by! { |rhs| preload_index[rhs] } if scope.order_values.any?
    records.uniq! if scope.distinct_value
    result[owner] = records
  end
end