class OccamsRecord::EagerLoaders::AdHocBase

Base class for eager loading ad hoc associations.

Attributes

name[R]

@return [String] association name

Public Class Methods

new(name, mapping, sql, binds: {}, model: nil, use: nil, &builder) click to toggle source

Initialize a new add hoc association.

@param name [Symbol] name of attribute to load records into @param mapping [Hash] a Hash with the key being the parent id and the value being fkey in the child @param sql [String] the SQL to query the associated records. Include a bind params called '%{ids}' for the foreign/parent ids. @param binds [Hash] any additional binds for your query. @param model [ActiveRecord::Base] optional - ActiveRecord model that represents what you're loading. required when using Sqlite. @param use [Array<Module>] optional - Ruby modules to include in the result objects (single or array) @yield eager load associations nested under this one

# File lib/occams-record/eager_loaders/ad_hoc_base.rb, line 25
def initialize(name, mapping, sql, binds: {}, model: nil, use: nil, &builder)
  @name, @mapping = name.to_s, mapping
  @sql, @binds, @use, @model = sql, binds, use, model
  @eager_loaders = EagerLoaders::Context.new(@model)
  instance_exec(&builder) if builder
end

Public Instance Methods

run(rows, query_logger: nil, measurements: nil) click to toggle source

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

@param rows [Array<OccamsRecord::Results::Row>] Array of rows used to calculate the query. @param query_logger [Array<String>]

# File lib/occams-record/eager_loaders/ad_hoc_base.rb, line 38
def run(rows, query_logger: nil, measurements: nil)
  fkey_binds = calc_fkey_binds rows
  assoc = if fkey_binds.all? { |_, vals| vals.any? }
            binds = @binds.merge(fkey_binds)
            RawQuery.new(@sql, binds, use: @use, eager_loaders: @eager_loaders, query_logger: query_logger, measurements: measurements).run
          else
            []
          end
  merge! assoc, rows
  nil
end

Private Instance Methods

calc_fkey_binds(rows) click to toggle source

Returns bind values from the parent rows.

@param rows [Array<OccamsRecord::Results::Row>] Array of rows used to calculate the query.

# File lib/occams-record/eager_loaders/ad_hoc_base.rb, line 57
def calc_fkey_binds(rows)
  @mapping.keys.reduce({}) { |a, fkey|
    a[fkey.to_s.pluralize.to_sym] = rows.reduce(Set.new) { |aa, row|
      begin
        val = row.send fkey
        aa << val if val
      rescue NoMethodError => e
        raise MissingColumnError.new(row, e.name)
      end
      aa
    }.to_a
    a
  }
end
merge!(assoc_rows, rows) click to toggle source
# File lib/occams-record/eager_loaders/ad_hoc_base.rb, line 72
def merge!(assoc_rows, rows)
  raise 'Not Implemented'
end