class Mongoid::Factory::Instantiator

A helper class for instantiating a model using either it’s type class directly, or via a type class specified via a discriminator key.

@api private

Attributes

attributes[R]

@return [ Hash | nil ] The Hash of attributes to use when

instantiating the model.
criteria[R]

@return [ Mongoid::Criteria | nil ] The criteria object to

use as a secondary source for the selected fields; also used when
setting the inverse association.
klass[R]

@return [ Mongoid::Document ] The primary model class being referenced

selected_fields[R]

@return [ Array | nil ] The list of field names that should

be explicitly (and exclusively) included in the new record.
type[R]

@return [ String | nil ] The identifier of the class that

should be loaded and instantiated, in the case of a polymorphic
class specification.

Public Class Methods

new(klass, attributes, criteria, selected_fields) click to toggle source

Creates a new Factory::Initiator.

@param klass [ Mongoid::Document ] The primary class to reference when

instantiating the model.

@param attributes [ Hash | nil ] (Optional) The hash of attributes to

use when instantiating the model.

@param criteria [ Mongoid::Criteria | nil ] (Optional) The criteria

object to use as a secondary source for the selected fields; also
used when setting the inverse association.

@param selected_fields [ Array | nil ] The list of field names that

should be explicitly (and exclusively) included in the new record.
# File lib/mongoid/factory.rb, line 46
def initialize(klass, attributes, criteria, selected_fields)
  @klass = klass
  @attributes = attributes
  @criteria = criteria
  @selected_fields = selected_fields ||
                     (criteria && criteria.options[:fields])
  @type = attributes && attributes[klass.discriminator_key]
end

Public Instance Methods

instance(execute_callbacks: Threaded.execute_callbacks?) click to toggle source

Builds and returns a new instance of the requested class.

@param execute_callbacks [ true | false ] Whether or not the Document

callbacks should be invoked with the new instance.

@raise [ Errors::UnknownModel ] when the requested type does not exist,

or if it does not respond to the `instantiate` method.

@return [ Mongoid::Document ] The new document instance.

# File lib/mongoid/factory.rb, line 64
def instance(execute_callbacks: Threaded.execute_callbacks?)
  if type.blank?
    instantiate_without_type(execute_callbacks)
  else
    instantiate_with_type(execute_callbacks)
  end
end

Private Instance Methods

constantize(type) click to toggle source

Attempts to convert the argument into a Class object by camelizing it and treating the result as the name of a constant.

@param type [ String ] The name of the type to constantize

@raise [ Errors::UnknownModel ] if the argument does not correspond to

an existing constant.

@return [ Class ] the Class that the type resolves to

# File lib/mongoid/factory.rb, line 127
def constantize(type)
  camelized = type.camelize
  camelized.constantize
rescue NameError
  raise Errors::UnknownModel.new(camelized, type)
end
constantized_type() click to toggle source

Retreive the ‘Class` instance of the requested type, either by finding it in the `klass` discriminator mapping, or by otherwise finding a Document model with the given name.

@return [ Mongoid::Document ] the requested Document model

# File lib/mongoid/factory.rb, line 107
def constantized_type
  @constantized_type ||= begin
    constantized = klass.get_discriminator_mapping(type) || constantize(type)

    # Check if the class is a Document class
    raise Errors::UnknownModel.new(camelized, type) unless constantized.respond_to?(:instantiate)

    constantized
  end
end
instantiate_with_type(execute_callbacks) click to toggle source

Instantiate the given ‘type`, which must map to another Mongoid::Document model.

@param [ true | false ] execute_callbacks Whether this method should

invoke document callbacks.

@return [ Document ] The instantiated document.

# File lib/mongoid/factory.rb, line 95
def instantiate_with_type(execute_callbacks)
  constantized_type.instantiate_document(
    attributes, selected_fields,
    execute_callbacks: execute_callbacks
  )
end
instantiate_without_type(execute_callbacks) click to toggle source

Instantiate the given class without any given subclass.

@param [ true | false ] execute_callbacks Whether this method should

invoke document callbacks.

@return [ Document ] The instantiated document.

# File lib/mongoid/factory.rb, line 80
def instantiate_without_type(execute_callbacks)
  klass.instantiate_document(attributes, selected_fields, execute_callbacks: execute_callbacks).tap do |obj|
    if criteria&.association && criteria&.parent_document
      obj.set_relation(criteria.association.inverse, criteria.parent_document)
    end
  end
end