Module: OccamsRecord::EagerLoaders::Builder
Overview
Methods for adding eager loading to a query.
Instance Method Summary collapse
-
#eager_load(assoc, scope = nil, select: nil, use: nil, as: nil) { ... } ⇒ OccamsRecord::Query
Specify an association to be eager-loaded.
-
#eager_load_many(name, mapping, sql, binds: {}, model: nil, use: nil) { ... } ⇒ Object
Specify some arbitrary SQL to be loaded into some arbitrary attribute (“name”).
-
#eager_load_one(name, mapping, sql, binds: {}, model: nil, use: nil) { ... } ⇒ Object
Specify some arbitrary SQL to be loaded into some arbitrary attribute (“name”).
Instance Method Details
#eager_load(assoc, scope = nil, select: nil, use: nil, as: nil) { ... } ⇒ OccamsRecord::Query
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.
32 33 34 35 36 37 38 39 |
# File 'lib/occams-record/eager_loaders.rb', line 32 def eager_load(assoc, scope = nil, select: nil, use: nil, as: nil, &eval_block) ref = @model ? @model.reflections[assoc.to_s] : nil ref ||= @model.subclasses.map(&:reflections).detect { |x| x.has_key? assoc.to_s }&.[](assoc.to_s) if @model raise "OccamsRecord: No assocation `:#{assoc}` on `#{@model&.name || '<model missing>'}` or subclasses" if ref.nil? scope ||= ->(q) { q.select select } if select @eager_loaders << eager_loader_for_association(ref).new(ref, scope, use: use, as: as, &eval_block) self end |
#eager_load_many(name, mapping, sql, binds: {}, model: nil, use: nil) { ... } ⇒ Object
Specify some arbitrary SQL to be loaded into some arbitrary attribute (“name”). The attribute will hold an array of 0 or more associated records.
In the example below, :parts is NOT an association on Widget. Though if it where it would be a has_many. The mapping argument says “The widget_id column in this table (parts) maps to the id column in the other table (widgets)”. The %ids bind param will be provided for you, and in this case will be all the id values from the main query.
res = OccamsRecord.
query(Widget.order("name")).
eager_load_many(:parts, {:widget_id => :id}, %(
SELECT * FROM parts WHERE widget_id IN (%{ids}) AND sku NOT IN (%{bad_skus})
), binds: {
bad_skus: ["G90023ASDf0"]
}).
run
98 99 100 101 |
# File 'lib/occams-record/eager_loaders.rb', line 98 def eager_load_many(name, mapping, sql, binds: {}, model: nil, use: nil, &eval_block) @eager_loaders << EagerLoaders::AdHocMany.new(name, mapping, sql, binds: binds, model: model, use: use, &eval_block) self end |
#eager_load_one(name, mapping, sql, binds: {}, model: nil, use: nil) { ... } ⇒ Object
Specify some arbitrary SQL to be loaded into some arbitrary attribute (“name”). The attribute will hold either one record or none.
In the example below, :category is NOT an association on Widget. Though if it where it would be a belongs_to. The mapping argument says “The id column in this table (categories) maps to the category_id column in the other table (widgets)”. The %ids bind param will be provided for you, and in this case will be all the category_id values from the main query.
res = OccamsRecord.
query(Widget.order("name")).
eager_load_one(:category, {:id => :category_id}, %(
SELECT * FROM categories WHERE id IN (%{ids}) AND name != %{bad_name}
), binds: {
bad_name: "Bad Category"
}).
run
67 68 69 70 |
# File 'lib/occams-record/eager_loaders.rb', line 67 def eager_load_one(name, mapping, sql, binds: {}, model: nil, use: nil, &eval_block) @eager_loaders << EagerLoaders::AdHocOne.new(name, mapping, sql, binds: binds, model: model, use: use, &eval_block) self end |