module Mongoid::Includes::EagerLoad

Public: Adds support for polymorphic and nested eager loading.

Public Instance Methods

eager_load(docs) click to toggle source

Override: Partitions the inclusions into the different types.

# File lib/mongoid/includes/eager_load.rb, line 8
def eager_load(docs)
  if eager_loadable?
    nested_inclusions, inclusions = criteria.inclusions.partition(&:nested?)
    polymorphic_inclusions, inclusions = inclusions.partition(&:polymorphic_belongs_to?)
    full_preload(docs, inclusions, polymorphic_inclusions, nested_inclusions)
  end

  docs
end
full_preload(docs, inclusions, polymorphic_inclusions, nested_inclusions) click to toggle source

Internal: Performs the normal inclusions first, which allows to perform the polymorphic eager loading. Nested inclusions are performed at the end.

# File lib/mongoid/includes/eager_load.rb, line 20
def full_preload(docs, inclusions, polymorphic_inclusions, nested_inclusions)
  preload(inclusions, docs)

  polymorphic_inclusions.each do |metadata|
    preload_polymorphic(metadata, docs)
  end

  preload_nested(nested_inclusions, docs)
end
preload_nested(nested_inclusions, docs) click to toggle source

Internal: The documents are grouped by the nested property, and all the includes by that property are processed as usual.

# File lib/mongoid/includes/eager_load.rb, line 43
def preload_nested(nested_inclusions, docs)
  nested_inclusions.group_by(&:from).each do |from, inclusions|
    preload(inclusions, docs.flat_map(&from).compact)
  end
end
preload_polymorphic(inclusion, docs) click to toggle source

Internal: Preloads each polymorphic includes, by grouping the documents by concrete type of the polymorphic relation, and making a query for each type.

# File lib/mongoid/includes/eager_load.rb, line 32
def preload_polymorphic(inclusion, docs)
  docs.group_by do |doc|
    doc.send(inclusion.inverse_type) # The {name}_type attribute in polymorphic relations.
  end.select { |type, _| type }.each do |type, docs|
    concrete_inclusion = inclusion.for_class_name(type)
    preload([concrete_inclusion], docs)
  end
end