123456789_123456789_123456789_123456789_123456789_

Class: Mongoid::Association::EagerLoad::PolymorphicPreloader Private

Relationships & Source Files
Inherits: Object
Defined in: lib/mongoid/association/eager_load/polymorphic_preloader.rb

Overview

Resolves a polymorphic belongs_to onto already-materialized root documents.

A polymorphic belongs_to can't be expressed as a $lookup: its target collection varies per document. So once the roots are materialized, the foreign keys are grouped by type, PolymorphicTargets resolves the documents for those keys, and the result is set on each document.

Class Method Summary

Instance Method Summary

Constructor Details

.new(association, root_class) ⇒ PolymorphicPreloader

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_preloader.rb', line 17

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

Instance Method Details

#assign(documents, targets) (private)

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_preloader.rb', line 41

def assign(documents, targets)
  documents.each do |document|
    type, key = reference_on(document)
    target = targets.dig(type, key) if type && key
    document.set_relation(@association.name, target)
  end
end

#keys_by_type(documents) (private)

The foreign keys on the documents grouped by polymorphic type, e.g. { "Printer" => [ id1 ], "Scanner" => [ id2 ] }.

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_preloader.rb', line 34

def keys_by_type(documents)
  documents.each_with_object({}) do |document, grouped|
    type, key = reference_on(document)
    (grouped[type] ||= []) << key if type && key
  end
end

#preload_into(documents)

Resolve and assign the polymorphic target on each of the documents.

Parameters:

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_preloader.rb', line 25

def preload_into(documents)
  targets = PolymorphicTargets.for(@association, keys_by_type(documents), @root_class)
  assign(documents, targets)
end

#reference_on(document) (private)

The [ type, key ] reference stored on the document for this association, or an empty pair when the document holds no such reference.

[ GitHub ]

  
# File 'lib/mongoid/association/eager_load/polymorphic_preloader.rb', line 51

def reference_on(document)
  type_field = @association.inverse_type
  key_field = @association.foreign_key
  return [] unless document.respond_to?(type_field) && document.respond_to?(key_field)

  [ document.send(type_field), document.send(key_field) ]
end