Module: Mongoid::Copyable

Extended by:
ActiveSupport::Concern
Included in:
Composable
Defined in:
lib/mongoid/copyable.rb

Overview

This module contains the behavior of Mongoid’s clone/dup of documents.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clone_with_hash(klass, attrs) ⇒ Document

Create clone of a document of the given klass with the given attributes hash. This is used recursively so that embedded associations are cloned safely.

Parameters:

  • The class of the document to create.

  • The hash of the attributes.

Returns:

  • The new document.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/mongoid/copyable.rb', line 44

def self.clone_with_hash(klass, attrs)
  dynamic_attrs = {}
  _attribute_names = klass.attribute_names
  attrs.reject! do |attr_name, value|
    unless _attribute_names.include?(attr_name)
      dynamic_attrs[attr_name] = value
      true
    end
  end

  Factory.build(klass, attrs).tap do |object|
    dynamic_attrs.each do |attr_name, value|
      assoc = object.embedded_relations[attr_name]
      if assoc&.one? && Hash === value
        object.send("#{attr_name}=", clone_with_hash(assoc.klass, value))
      elsif assoc&.many? && Array === value
        docs = value.map { |h| clone_with_hash(assoc.klass, h) }
        object.send("#{attr_name}=", docs)
      elsif object.respond_to?("#{attr_name}=")
        object.send("#{attr_name}=", value)
      else
        object.attributes[attr_name] = value
      end
    end
  end
end

Instance Method Details

#cloneDocument Also known as: dup

Clone or dup the current Document. This will return all attributes with the exception of the document’s id, and will reset all the instance variables.

This clone also includes embedded documents. If there is an _id field in the embedded document, it will be maintained, unlike the root’s _id.

If cloning an embedded child, the embedded parent is not cloned and the embedded_in association is not set.

Examples:

Clone the document.

document.clone

Returns:

  • The new document.



24
25
26
27
28
29
30
31
# File 'lib/mongoid/copyable.rb', line 24

def clone
  # @note This next line is here to address #2704, even though having an
  # _id and id field in the document would cause problems with Mongoid
  # elsewhere. Note this is only done on the root document as we want
  # to maintain the same _id on the embedded documents.
  attrs = clone_document.except(*self.class.id_fields)
  Copyable.clone_with_hash(self.class, attrs)
end