module Sequel::Plugins::EagerGraphEager::DatasetMethods

Public Instance Methods

eager_graph_eager(dependency_chain, *assocs) click to toggle source

Specify for the given dependency chain, after loading objects for the current dataset via eager_graph, eagerly load the given associations at that point in the dependency chain.

dependency_chain

Array of association symbols, with the first association symbol specifying an association in the dataset's model, the next association specifying an association in the previous association's associated model, and so on.

assocs

Symbols or hashes specifying associations to eagerly load at the point specified by the dependency chain.

# File lib/sequel/plugins/eager_graph_eager.rb, line 73
def eager_graph_eager(dependency_chain, *assocs)
  unless dependency_chain.is_a?(Array) && dependency_chain.all?{|s| s.is_a?(Symbol)} && !dependency_chain.empty?
    raise Error, "eager_graph_eager first argument must be array of symbols"
  end

  current = model
  deps = dependency_chain.map do |dep|
    unless ref = current.association_reflection(dep)
      raise Error, "invalid association #{dep.inspect} for #{current.inspect}"
    end
    current = ref.associated_class
    [dep, ref.returns_array?]
  end
  assocs = current.dataset.send(:eager_options_for_associations, assocs)

  deps.each(&:freeze)
  deps.unshift(current)
  deps.freeze

  assocs.freeze

  if h = @opts[:eager_graph_eager]
    h = Hash[h]
    h[deps] = assocs
  else
    h = {deps => assocs}
  end

  clone(:eager_graph_eager=>h.freeze)
end

Protected Instance Methods

eager_graph_build_associations(rows) click to toggle source

After building objects from the rows, if #eager_graph_eager has been called on the datasets, for each dependency chain specified, eagerly load the appropriate associations.

Calls superclass method
# File lib/sequel/plugins/eager_graph_eager.rb, line 109
def eager_graph_build_associations(rows)
  objects = super

  if eager_data = @opts[:eager_graph_eager]
    eager_data.each do |deps, assocs|
      current = objects

      last_class, *deps = deps
      deps.each do |dep, is_multiple|
        current_assocs = current.map(&:associations)

        if is_multiple
          current = current_assocs.flat_map{|a| a[dep]}
        else
          current = current_assocs.map{|a| a[dep]}
          current.compact!
        end

        current.uniq!(&:object_id)
      end

      last_class.dataset.send(:eager_load, current, assocs)
    end
  end

  objects
end