Module: Mongoid::Includes::EagerLoad

Defined in:
lib/mongoid/includes/eager_load.rb

Overview

Public: Adds support for polymorphic and nested eager loading.

Instance Method Summary collapse

Instance Method Details

#eager_load(docs) ⇒ Object

Override: Partitions the inclusions into the different types.



8
9
10
11
12
13
14
15
16
# 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) ⇒ Object

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



20
21
22
23
24
25
26
27
28
# 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 ||
    preload_polymorphic(, docs)
  end

  preload_nested(nested_inclusions, docs)
end

#preload_nested(nested_inclusions, docs) ⇒ Object

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



43
44
45
46
47
# 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) ⇒ Object

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



32
33
34
35
36
37
38
39
# 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