Class: OccamsRecord::EagerLoaders::Context
- Inherits:
-
Object
- Object
- OccamsRecord::EagerLoaders::Context
- Defined in:
- lib/occams-record/eager_loaders/context.rb
Overview
A container for all eager loading on a particular Active Record model. Usually the context is initialized with the model, and all eager loaders are immediately initialized. Any errors (like a wrong association name ) will be thrown immediately and before any queries are run.
However, in certain situations the model cannot be known until runtime (e.g. eager loading off of a polymorphic association). In these cases the model won’t be set, or the eager loaders fully initialized, until the parent queries have run. This means that certain errors (like a wrong association name) won’t be noticed until very late, after queries have started running.
Instance Attribute Summary collapse
Instance Method Summary collapse
-
#<<(loader) ⇒ OccamsRecord::EagerLoaders::Base
Append an already-initialized eager loader.
-
#add(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, active_record_fallback: nil) { ... } ⇒ OccamsRecord::EagerLoaders::Base
Specify an association to be eager-loaded.
-
#each ⇒ Object
Iterate over each loader.
-
#initialize(model = nil, tracer: nil, polymorphic: false) ⇒ Context
constructor
Initialize a new eager loading context.
-
#names ⇒ Array<String>
Return the names of the associations being loaded.
-
#run!(rows, query_logger: nil, measurements: nil) ⇒ Object
Performs all eager loading in this context (and in any nested ones).
Constructor Details
#initialize(model = nil, tracer: nil, polymorphic: false) ⇒ Context
Initialize a new eager loading context.
27 28 29 30 31 32 |
# File 'lib/occams-record/eager_loaders/context.rb', line 27 def initialize(model = nil, tracer: nil, polymorphic: false) @model, @polymorphic = model, polymorphic @tracer = tracer || OccamsRecord::EagerLoaders::Tracer.new("root") @loaders = [] @dynamic_loaders = [] end |
Instance Attribute Details
#model ⇒ ActiveRecord::Base
15 16 17 |
# File 'lib/occams-record/eager_loaders/context.rb', line 15 def model @model end |
#tracer ⇒ OccamsRecord::EagerLoaders::Tracer (readonly)
18 19 20 |
# File 'lib/occams-record/eager_loaders/context.rb', line 18 def tracer @tracer end |
Instance Method Details
#<<(loader) ⇒ OccamsRecord::EagerLoaders::Base
Append an already-initialized eager loader.
63 64 65 66 |
# File 'lib/occams-record/eager_loaders/context.rb', line 63 def <<(loader) @loaders << loader loader end |
#add(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, active_record_fallback: nil) { ... } ⇒ OccamsRecord::EagerLoaders::Base
Specify an association to be eager-loaded. For maximum memory savings, only SELECT the colums you actually need.
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.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/occams-record/eager_loaders/context.rb', line 84 def add(assoc, scope = nil, select: nil, use: nil, as: nil, from: nil, optimizer: :select, active_record_fallback: nil, &builder) if from real_assoc = from custom_name = assoc elsif as real_assoc = assoc custom_name = as else real_assoc = assoc custom_name = nil end if @model loader = build_loader!(real_assoc, custom_name, scope, select, use, optimizer, builder, active_record_fallback) @loaders << loader loader else @dynamic_loaders << [real_assoc, custom_name, scope, select, use, optimizer, builder, active_record_fallback] nil end end |
#each ⇒ Object
Iterate over each loader
121 122 123 124 |
# File 'lib/occams-record/eager_loaders/context.rb', line 121 def each return @loaders.each unless block_given? @loaders.each { |l| yield l } end |
#names ⇒ Array<String>
Return the names of the associations being loaded.
52 53 54 55 |
# File 'lib/occams-record/eager_loaders/context.rb', line 52 def names @loaders.map(&:name) | @loaders.select { |l| l.respond_to? :through_name }.map(&:through_name) # TODO make not hacky end |
#run!(rows, query_logger: nil, measurements: nil) ⇒ Object
Performs all eager loading in this context (and in any nested ones).
112 113 114 115 116 117 118 |
# File 'lib/occams-record/eager_loaders/context.rb', line 112 def run!(rows, query_logger: nil, measurements: nil) raise "Cannot run eager loaders when @model has not been set!" if @dynamic_loaders.any? and @model.nil? @loaders.each { |loader| loader.run(rows, query_logger: query_logger, measurements: measurements) } nil end |