Module: Mongoid::Copyable
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
ActiveSupport::Concern
|
|
Defined in: | lib/mongoid/copyable.rb |
Overview
This module contains the behavior of Mongoid’s clone/dup of documents.
Class Method Summary
-
.clone_with_hash(klass, attrs) ⇒ Document
private
Create clone of a document of the given klass with the given attributes hash.
Instance Method Summary
-
#clone ⇒ Document
(also: #dup)
Clone or dup the current
Document
. -
#dup
Alias for #clone.
-
#clone_document
private
Internal use only
Internal use only
Clone the document attributes.
-
#process_localized_attributes(klass, attrs)
private
Internal use only
Internal use only
When cloning, if the document has localized fields we need to ensure they are properly processed in the clone.
Class Method Details
.clone_with_hash(klass, attrs) ⇒ Document (private)
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.
# 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. [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
#clone ⇒ Document 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.
# 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
#clone_document (private)
Clone the document attributes
# File 'lib/mongoid/copyable.rb', line 77
def clone_document attrs = as_attributes.__deep_copy__ process_localized_attributes(self, attrs) attrs end
#dup
Alias for #clone.
# File 'lib/mongoid/copyable.rb', line 32
alias :dup :clone
#process_localized_attributes(klass, attrs) (private)
When cloning, if the document has localized fields we need to ensure they are properly processed in the clone.
# File 'lib/mongoid/copyable.rb', line 92
def process_localized_attributes(klass, attrs) klass.localized_fields.keys.each do |name| if value = attrs.delete(name) attrs["#{name}_translations"] = value end end klass. .each do |_, association| next unless attrs.present? && attrs[association.key].present? if association.is_a?(Association::Embedded::EmbedsMany) attrs[association.key].each do |attr| = if type = attr[self.class.discriminator_key] association.relation_class.get_discriminator_mapping(type) || association.relation_class else association.relation_class end process_localized_attributes(, attr) end else process_localized_attributes(association.klass, attrs[association.key]) end end end