Class: OccamsRecord::EagerLoaders::Through

Inherits:
Base
  • Object
show all
Defined in:
lib/occams-record/eager_loaders/through.rb

Overview

Handles :through associations for has_many and has_one. Polymorphic associations are not supported.

Defined Under Namespace

Classes: Link

Instance Attribute Summary

Attributes inherited from Base

#eager_loaders, #name, #tracer

Instance Method Summary collapse

Methods inherited from Base

#scope

Methods included from Builder

#eager_load, #eager_load_many, #eager_load_one, #nest

Constructor Details

#initialize(ref, scope = nil, use: nil, as: nil, optimizer: :select, parent: nil, active_record_fallback: nil, &builder) ⇒ Through

See documentation for OccamsRecord::EagerLoaders::Base.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/occams-record/eager_loaders/through.rb', line 12

def initialize(ref, scope = nil, use: nil, as: nil, optimizer: :select, parent: nil, active_record_fallback: nil, &builder)
  super

  unless @ref.macro == :has_one or @ref.macro == :has_many
    raise ArgumentError, "#{@ref.active_record.name}##{@ref.name} cannot be eager loaded because only `has_one` and `has_many` are supported for `through` associations"
  end
  if (polys = @ref.chain.select(&:polymorphic?)).any?
    names = polys.map { |r| "#{r.active_record.name}##{r.name}" }
    raise ArgumentError, "#{@ref.active_record.name}##{@ref.name} cannot be eager loaded because these `through` associations are polymorphic: #{names.join ', '}"
  end
  unless @optimizer == :none or @optimizer == :select
    raise ArgumentError, "Unrecognized optimizer '#{@optimizer}' (valid options are :none, :select)"
  end

  chain = @ref.chain.reverse
  @chain = chain.each_with_index.map { |x, i|
    Link.new(x.source_reflection.name, x.source_reflection.macro, x, chain[i + 1])
  }
  @chain[-1].name = @as if @as and @chain.any?
  @loader = build_loader
end

Instance Method Details

#run(rows, query_logger: nil, measurements: nil) ⇒ Object



38
39
40
41
42
43
44
45
# File 'lib/occams-record/eager_loaders/through.rb', line 38

def run(rows, query_logger: nil, measurements: nil)
  @loader.run(rows, query_logger: query_logger, measurements: measurements)
  attr_set = "#{name}="
  rows.each do |row|
    row.send(attr_set, reduce(row))
  end
  nil
end

#through_nameObject



34
35
36
# File 'lib/occams-record/eager_loaders/through.rb', line 34

def through_name
  @loader.name
end