Class: OccamsRecord::EagerLoaders::Base

Inherits:
Object
  • Object
show all
Includes:
Builder
Defined in:
lib/occams-record/eager_loaders/base.rb

Overview

Base class for eagoer loading an association. IMPORTANT eager loaders MUST remain stateless after initialization!

Direct Known Subclasses

BelongsTo, Habtm, HasOne, Through

Instance Attribute Summary collapse

Instance Method Summary collapse

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) { ... } ⇒ Base

ActiveRecord::Relation on which you may call all the normal query hethods (select, where, etc) as well as any scopes you’ve defined on the model.

Parameters:

  • ref (ActiveRecord::Association)

    the ActiveRecord association

  • scope (Proc) (defaults to: nil)

    a scope to apply to the query (optional). It will be passed an

  • use (Array(Module)) (defaults to: nil)

    optional Module to include in the result class (single or array)

  • as (Symbol) (defaults to: nil)

    Load the association usign a different attribute name

  • optimizer (Symbol) (defaults to: :select)

    Only used for ‘through` associations. Options are :none (load all intermediate records) | :select (load all intermediate records but only SELECT the necessary columns)

  • parent (OccamsRecord::EagerLoaders::Tracer) (defaults to: nil)

    the eager loader this one is nested under (if any)

  • active_record_fallback (Symbol) (defaults to: nil)

    If passed, missing methods will be forwarded to an ActiveRecord instance. Options are :lazy (allow lazy loading in the AR record) or :strict (require strict loading)

Yields:

  • perform eager loading on this association (optional)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/occams-record/eager_loaders/base.rb', line 29

def initialize(ref, scope = nil, use: nil, as: nil, optimizer: :select, parent: nil, active_record_fallback: nil, &builder)
  @ref, @scopes, @use, @as = ref, Array(scope), use, as
  @model = ref.klass
  @name = (as || ref.name).to_s
  @tracer = Tracer.new(name, parent)
  @eager_loaders = EagerLoaders::Context.new(@model, tracer: @tracer)
  @active_record_fallback = active_record_fallback
  @optimizer = optimizer
  if builder
    if builder.arity > 0
      builder.call(self)
    else
      instance_exec(&builder)
    end
  end
end

Instance Attribute Details

#eager_loadersOccamsRecord::EagerLoaders::Context (readonly)



16
17
18
# File 'lib/occams-record/eager_loaders/base.rb', line 16

def eager_loaders
  @eager_loaders
end

#nameString (readonly)

Returns association name.

Returns:

  • (String)

    association name



10
11
12
# File 'lib/occams-record/eager_loaders/base.rb', line 10

def name
  @name
end

#tracerOccamsRecord::EagerLoaders::Tracer | nil (readonly)

Returns a reference to this eager loader and its parent (if any).

Returns:



13
14
15
# File 'lib/occams-record/eager_loaders/base.rb', line 13

def tracer
  @tracer
end

Instance Method Details

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

Run the query and merge the results into the given rows.

Parameters:

  • rows (Array<OccamsRecord::Results::Row>)

    Array of rows used to calculate the query.

  • query_logger (Array<String>) (defaults to: nil)


66
67
68
69
70
71
72
# File 'lib/occams-record/eager_loaders/base.rb', line 66

def run(rows, query_logger: nil, measurements: nil)
  query(rows) { |*args|
    assoc_rows = args[0] ? Query.new(args[0], use: @use, eager_loaders: @eager_loaders, query_logger: query_logger, measurements: measurements, active_record_fallback: @active_record_fallback).run : []
    merge! assoc_rows, rows, *args[1..-1]
  }
  nil
end

#scope {|ActiveRecord::Relation| ... } ⇒ Object

An alternative to passing a “scope” lambda to the constructor. Your block is passed the query so you can call select, where, order, etc on it.

If you call scope multiple times, the results will be additive.

Yields:

  • (ActiveRecord::Relation)

    a relation to modify with select, where, order, etc

Returns:

  • self



55
56
57
58
# File 'lib/occams-record/eager_loaders/base.rb', line 55

def scope(&scope)
  @scopes << scope if scope
  self
end