Module: Mongoid::Association::EagerLoadable

Included in:
Contextual::Memory, Contextual::Mongo, Contextual::Mongo::DocumentsLoader
Defined in:
lib/mongoid/association/eager_loadable.rb

Overview

This module defines the eager loading behavior for criteria.

Instance Method Summary collapse

Instance Method Details

#eager_load(docs) ⇒ Array<Mongoid::Document>

Load the associations for the given documents.

Parameters:

  • The documents.

Returns:

  • The given documents.



25
26
27
28
29
30
31
# File 'lib/mongoid/association/eager_loadable.rb', line 25

def eager_load(docs)
  docs.tap do |d|
    if eager_loadable?
      preload(criteria.inclusions, d)
    end
  end
end

#eager_loadable? ⇒ true | false

Indicates whether the criteria has association inclusions which should be eager loaded.

Returns:

  • Whether to eager load.



16
17
18
# File 'lib/mongoid/association/eager_loadable.rb', line 16

def eager_loadable?
  !criteria.inclusions.empty?
end

#preload(associations, docs) ⇒ Object

Load the associations for the given documents. This will be done recursively to load the associations of the given documents' associated documents.

Parameters:

  • The associations to load.

  • The documents.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/mongoid/association/eager_loadable.rb', line 40

def preload(associations, docs)
  assoc_map = associations.group_by(&:inverse_class_name)
  docs_map = {}
  queue = [ klass.to_s ]

  # account for single-collection inheritance
  queue.push(klass.root_class.to_s) if klass != klass.root_class

  while klass = queue.shift
    if as = assoc_map.delete(klass)
      as.each do |assoc|
        queue << assoc.class_name

        # If this class is nested in the inclusion tree, only load documents
        # for the association above it. If there is no parent association,
        # we will include documents from the documents passed to this method.
        ds = docs
        if assoc.parent_inclusions.length > 0
          ds = assoc.parent_inclusions.map{ |p| docs_map[p].to_a }.flatten
        end

        res = assoc.relation.eager_loader([assoc], ds).run

        docs_map[assoc.name] ||= [].to_set
        docs_map[assoc.name].merge(res)
      end
    end
  end
end