module Mongoid::Document

This is the base module for all domain objects that need to be persisted to the database as documents.

Constants

ILLEGAL_KEY

Regex for matching illegal BSON keys. Note that bson 4.1 has the constant BSON::String::ILLEGAL_KEY that should be used instead. When ruby driver 2.3.0 is released and Mongoid can be updated to require >= 2.3.0, the BSON constant can be used.

Attributes

__selected_fields[RW]
new_record[R]

Public Class Methods

new(attrs = nil, &block) click to toggle source

Instantiate a new Document, setting the Document’s attributes if given. If no attributes are provided, they will be initialized with an empty Hash.

If a primary key is defined, the document’s id will be set to that key, otherwise it will be set to a fresh BSON::ObjectId string.

@example Create a new document.

Person.new(:title => 'Sir')

@param [ Hash ] attrs The attributes to set up the document with.

@return [ Document ] A new document.

# File lib/mongoid/document.rb, line 104
def initialize(attrs = nil, &block)
  construct_document(attrs, &block)
end

Public Instance Methods

_handle_callbacks_after_instantiation(execute_callbacks) { |self| ... } click to toggle source

Handles the setup and execution of callbacks, if callbacks are to be executed; otherwise, adds the appropriate callbacks to the pending callbacks list.

@param execute_callbacks [ true | false ] Whether callbacks should be

executed or not.

@api private

# File lib/mongoid/document.rb, line 186
def _handle_callbacks_after_instantiation(execute_callbacks)
  if execute_callbacks
    apply_defaults
    yield self if block_given?
    run_callbacks(:find) unless _find_callbacks.empty?
    run_callbacks(:initialize) unless _initialize_callbacks.empty?
  else
    yield self if block_given?
    self.pending_callbacks += %i[ apply_defaults find initialize ]
  end
end
as_document() click to toggle source

Return a hash of the entire document hierarchy from this document and below. Used when the attributes are needed for everything and not just the current document.

@example Get the full hierarchy.

person.as_document

@return [ Hash ] A hash of all attributes in the hierarchy.

# File lib/mongoid/document.rb, line 136
def as_document
  BSON::Document.new(as_attributes)
end
becomes(klass) click to toggle source

Returns an instance of the specified class with the attributes, errors, and embedded documents of the current document.

@example Return a subclass document as a superclass instance.

manager.becomes(Person)

@raise [ ArgumentError ] If the class doesn’t include Mongoid::Document

@param [ Class ] klass The class to become.

@return [ Document ] An instance of the specified class.

# File lib/mongoid/document.rb, line 151
def becomes(klass)
  mongoid_document_check!(klass)

  became = klass.new(clone_document)
  became.internal_state = internal_state

  became
end
freeze() click to toggle source

Freezes the internal attributes of the document.

@example Freeze the document

document.freeze

@return [ Document ] The document.

# File lib/mongoid/document.rb, line 51
def freeze
  as_attributes.freeze and self
end
frozen?() click to toggle source

Checks if the document is frozen

@example Check if frozen

document.frozen?

@return [ true | false ] True if frozen, else false.

# File lib/mongoid/document.rb, line 61
def frozen?
  attributes.frozen?
end
hash() click to toggle source

Delegates to identity in order to allow two records of the same identity to work with something like:

[ Person.find(1), Person.find(2), Person.find(3) ] &
[ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]

@example Get the hash.

document.hash

@return [ Integer ] The hash of the document’s identity.

# File lib/mongoid/document.rb, line 75
def hash
  identity.hash
end
identity() click to toggle source

A Document’s is identified absolutely by its class and database id:

Person.first.identity #=> [Person, BSON::ObjectId(‘4f775130a04745933a000003’)]

@example Get the identity

document.identity

@return [ Array ] An array containing [document.class, document._id]

# File lib/mongoid/document.rb, line 87
def identity
  [ self.class, _id ]
end
internal_state=(state) click to toggle source

Sets the internal state of this document. Used only by becomes to help initialize a retyped document.

@param [ Hash ] state The map of internal state values.

@api private

# File lib/mongoid/document.rb, line 166
def internal_state=(state)
  self._id = state[:id]
  @changed_attributes = state[:changed_attributes]
  @errors = ActiveModel::Errors.new(self).tap { |e| e.copy!(state[:errors]) }
  @new_record = state[:new_record]
  @destroyed = state[:destroyed]

  update_discriminator(state[:discriminator_key_was])

  mark_persisted_state_for_embedded_documents(state[:new_record])
end
model_name() click to toggle source

Return the model name of the document.

@example Return the model name.

document.model_name

@return [ String ] The model name.

# File lib/mongoid/document.rb, line 114
def model_name
  self.class.model_name
end
to_key() click to toggle source

Return the key value for the document.

@example Return the key.

document.to_key

@return [ String ] The id of the document or nil if new.

# File lib/mongoid/document.rb, line 124
def to_key
  (persisted? || destroyed?) ? [ _id.to_s ] : nil
end

Private Instance Methods

add_attributes_for_relation(name, meta) click to toggle source

Adds the attributes for the given relation to the document’s attributes.

@param name [ String | Symbol ] the name of the relation to add @param meta [ Mongoid::Assocation::Relatable ] the relation object

# File lib/mongoid/document.rb, line 283
def add_attributes_for_relation(name, meta)
  relation, stored = send(name), meta.store_as
  return unless attributes.key?(stored) || !relation.blank?

  if relation.nil?
    attributes.delete(stored)
  else
    attributes[stored] = relation.send(:as_attributes)
  end
end
as_attributes() click to toggle source

Returns a hash of the attributes.

Note this method modifies the attributes hash that already exists on the class and returns it. This means that the hash returned by this method refers to the same hash as calling attributes on the instance. See MONGOID-4476 for an explanation on how this is used.

@return [ Hash ] The attributes hash.

# File lib/mongoid/document.rb, line 267
def as_attributes
  return attributes if frozen?

  embedded_relations.each_pair do |name, meta|
    without_autobuild do
      add_attributes_for_relation(name, meta)
    end
  end

  attributes
end
construct_document(attrs = nil, options = {}) { |self| ... } click to toggle source

Does the construction of a document.

@param [ Hash ] attrs The attributes to set up the document with. @param [ Hash ] options The options to use.

@option options [ true | false ] :execute_callbacks Flag specifies

whether callbacks should be run.

@return [ Document ] A new document.

@note A Ruby 2.x bug prevents the options hash from being keyword

arguments. Once we drop support for Ruby 2.x, we can reimplement
the options hash as keyword arguments.
See https://bugs.ruby-lang.org/issues/15753

@api private

# File lib/mongoid/document.rb, line 216
def construct_document(attrs = nil, options = {})
  execute_callbacks = options.fetch(:execute_callbacks, Threaded.execute_callbacks?)

  self._parent = nil
  _building do
    prepare_to_process_attributes

    process_attributes(attrs) do
      yield(self) if block_given?
    end
    @attributes_before_type_cast = @attributes.merge(attributes_before_type_cast)

    resolve_post_construction_callbacks(execute_callbacks)
  end
  self
end
internal_state() click to toggle source

Constructs a hash representing the internal state of this object, suitable for passing to internal_state=.

@return [ Hash ] the map of internal state values

# File lib/mongoid/document.rb, line 310
def internal_state
  {
    id: _id,
    changed_attributes: changed_attributes,
    errors: errors,
    new_record: new_record?,
    destroyed: destroyed?,
    discriminator_key_was: self.class.discriminator_value
  }
end
logger() click to toggle source

Returns the logger

@return [ Logger ] The configured logger or a default Logger instance.

# File lib/mongoid/document.rb, line 245
def logger
  Mongoid.logger
end
mark_persisted_state_for_embedded_documents(new_record) click to toggle source

Marks all embedded documents with the given “new_record” state.

@param [ true | false ] new_record whether or not the embedded records

should be flagged as new records or not.
# File lib/mongoid/document.rb, line 334
def mark_persisted_state_for_embedded_documents(new_record)
  embedded_relations.each_pair do |name, _meta|
    without_autobuild do
      relation = __send__(name)
      Array.wrap(relation).each do |r|
        r.instance_variable_set(:@new_record, new_record)
      end
    end
  end
end
model_key() click to toggle source

Get the name of the model used in caching.

@example Get the model key.

model.model_key

@return [ String ] The model key.

# File lib/mongoid/document.rb, line 255
def model_key
  @model_key ||= self.class.model_name.cache_key
end
mongoid_document_check!(klass) click to toggle source

Checks that the given argument is an instance of ‘Mongoid::Document`.

@param klass [ Class ] The class to test.

@raise [ ArgumentError ] if the class does not include

Mongoid::Document.
# File lib/mongoid/document.rb, line 300
def mongoid_document_check!(klass)
  return if klass.include?(Mongoid::Document)

  raise ArgumentError, 'A class which includes Mongoid::Document is expected'
end
prepare_to_process_attributes() click to toggle source

Initializes the object state prior to attribute processing; this is called only from construct_document.

# File lib/mongoid/document.rb, line 235
def prepare_to_process_attributes
  @new_record = true
  @attributes ||= {}
  apply_pre_processed_defaults
  apply_default_scoping
end
resolve_post_construction_callbacks(execute_callbacks) click to toggle source

Either executes or enqueues the post-construction callbacks.

@param [ true | false ] execute_callbacks whether the callbacks

should be executed (true) or enqueued (false)
# File lib/mongoid/document.rb, line 349
def resolve_post_construction_callbacks(execute_callbacks)
  if execute_callbacks
    apply_post_processed_defaults
    run_callbacks(:initialize) unless _initialize_callbacks.empty?
  else
    pending_callbacks << :apply_post_processed_defaults
    pending_callbacks << :initialize
  end
end
update_discriminator(key_was) click to toggle source

Updates the value of the discriminator_key for this object, setting its previous value to ‘key_was`.

@param key_was [ String ] the previous value of the discriminator key.

# File lib/mongoid/document.rb, line 325
def update_discriminator(key_was)
  changed_attributes[self.class.discriminator_key] = key_was
  self[self.class.discriminator_key] = self.class.discriminator_value
end