123456789_123456789_123456789_123456789_123456789_

Class: Mongoid::Association::EagerLoad::SameDatabaseTargets Private

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: Mongoid::Association::EagerLoad::PolymorphicTargets
Defined in: lib/mongoid/association/eager_load/polymorphic_targets.rb

Overview

Targets that live in the root's own database. A $lookup can reach them, so every type is fetched together in one $facet aggregation against the root collection.

For { 'Printer' => [ id1 ], 'Scanner' => [ id2 ] } it runs:

[
{ '$limit' => 1 },   # one input doc, so each facet branch runs once
{ '$facet' => {      # run one $lookup per type within a single query
  'Printer' => [ { '$lookup' => { 'from' => 'printers', ... } }, ... ],
  'Scanner' => [ { '$lookup' => { 'from' => 'scanners', ... } }, ... ]
} }
]

Class Method Summary

PolymorphicTargets - Inherited

.for

Resolve every polymorphic target for the foreign keys grouped by type.

.new,
.in_root_database?

Whether the type's model shares the root's database (and client): exactly what a $lookup from the root collection can reach.

Instance Method Summary

PolymorphicTargets - Inherited

#fetch,
#indexed

The raw documents instantiated and indexed by their primary key.

#model_for, #primary_key

Constructor Details

.new(association, keys_by_type, root_class) ⇒ SameDatabaseTargets

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_targets.rb', line 86

def initialize(association, keys_by_type, root_class)
  super(association, keys_by_type)
  @root_class = root_class
end

Instance Method Details

#branch_for(collection_name, keys) (private)

::Mongoid::Association::One $facet branch: the documents in collection_name whose primary key is among keys, exposed under "matches".

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_targets.rb', line 112

def branch_for(collection_name, keys)
  [
    { '$lookup' => {
      'from' => collection_name,
      'pipeline' => [
        { '$match' => {
          primary_key => { '$in' => keys.uniq }
        } }
      ],
      'as' => 'matches'
    } },
    { '$project' => {
      '_id' => 0,
      'matches' => 1
    } }
  ]
end

#facets (private)

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_targets.rb', line 104

def facets
  @keys_by_type.to_h do |type, keys|
    [ type, branch_for(model_for(type).collection.name, keys) ]
  end
end

#fetchHash

Returns:

  • (Hash)

    The targets, as { type => { primary_key => document } }.

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_targets.rb', line 92

def fetch
  return {} if @keys_by_type.empty?

  aggregated = @root_class.collection.aggregate([ { '$limit' => 1 }, { '$facet' => facets } ]).first
  aggregated.to_h do |type, branch|
    # $limit => 1 makes each branch yield a single wrapper holding the matches.
    [ type, indexed(branch.first['matches'], model_for(type)) ]
  end
end