Class: Mongoid::Association::EagerLoad::DiscriminatedInclusion Private

Inherits:
Inclusion
  • Object
show all
Defined in:
lib/mongoid/association/eager_load/discriminated_inclusion.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Loads an inclusion that more than one subclass defines under the same name but pointing at different targets. A single $lookup can't serve them: they would all write to the same field and overwrite one another. So each subclass's inclusion is contributed into its own temporary field, carrying its own nested children, and a $set then routes every document to the field for its own type, by the discriminator.

For Machine.eager_load(:widgets), where Lathe#widgets => Cog and Press#widgets => Belt, it emits:

{ '$lookup' => { 'from' => 'cogs',  ..., 'as' => '__eager_load_widgets_Lathe' } },
{ '$lookup' => { 'from' => 'belts', ..., 'as' => '__eager_load_widgets_Press' } },
{ '$set' => {
'widgets' => { '$switch' => { 'branches' => [   # route each document to its
  { 'case' => { '$eq' => [ '$_type', 'Lathe' ] }, 'then' => '$__eager_load_widgets_Lathe' },  # own type's matches
  { 'case' => { '$eq' => [ '$_type', 'Press' ] }, 'then' => '$__eager_load_widgets_Press' }
], 'default' => [] } }
} },
{ '$unset' => [ '__eager_load_widgets_Lathe', '__eager_load_widgets_Press' ] }

Instance Method Summary collapse

Constructor Details

#initialize(nodes) ⇒ DiscriminatedInclusion

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of DiscriminatedInclusion.



30
31
32
33
# File 'lib/mongoid/association/eager_load/discriminated_inclusion.rb', line 30

def initialize(nodes)
  super()
  @nodes = nodes
end

Instance Method Details

#contribute(destination, _chain) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Append each subclass's lookup (into its own temporary field), the routing $set, and the cleanup $unset.

Parameters:

  • destination (Array<Hash>)

    The pipeline the stages are appended to.



39
40
41
42
43
# File 'lib/mongoid/association/eager_load/discriminated_inclusion.rb', line 39

def contribute(destination, _chain)
  fields = @nodes.map { |node| [ node, contribute_into_temporary(destination, node) ] }
  destination << route_by_type(fields)
  destination << { '$unset' => fields.map { |_node, field| field } }
end