module Mongoid::Traversable
Provides behaviour around traversing the document graph.
@since 4.0.0
Public Instance Methods
Get all child Documents
to this Document
, going n
levels deep if necessary. This is used when calling update persistence
operations from the root document, where changes in the entire tree need to
be determined. Note that persistence from the embedded documents will
always be preferred, since they are optimized calls… This operation can get
expensive in domains with large hierarchies.
@example Get all the document's children.
person._children
@return [ Array<Document> ] All child documents in the hierarchy.
# File lib/mongoid/traversable.rb, line 28 def _children @__children ||= collect_children end
# File lib/mongoid/traversable.rb, line 9 def _parent @__parent ||= nil end
# File lib/mongoid/traversable.rb, line 13 def _parent=(p) @__parent = p end
Resets the memoized children on the object. Called internally when an embedded array changes size.
@api semiprivate
@example Reset the memoized children.
document._reset_memoized_children!
@return [ nil ] nil.
@since 5.0.0
# File lib/mongoid/traversable.rb, line 140 def _reset_memoized_children! _parent._reset_memoized_children! if _parent @__children = nil end
Return the root document in the object graph. If the current document is the root object in the graph it will return self.
@example Get the root document in the hierarchy.
document._root
@return [ Document ] The root document in the hierarchy.
# File lib/mongoid/traversable.rb, line 152 def _root object = self while (object._parent) do object = object._parent; end object end
Is this document the root document of the hierarchy?
@example Is the document the root?
document._root?
@return [ true, false ] If the document is the root.
@since 3.1.0
# File lib/mongoid/traversable.rb, line 166 def _root? _parent ? false : true end
Collect all the children of this document.
@example Collect all the children.
document.collect_children
@return [ Array<Document> ] The children.
@since 2.4.0
# File lib/mongoid/traversable.rb, line 40 def collect_children children = [] embedded_relations.each_pair do |name, association| without_autobuild do child = send(name) Array.wrap(child).each do |doc| children.push(doc) children.concat(doc._children) end if child end end children end
Marks all children as being persisted.
@example Flag all the children.
document.flag_children_persisted
@return [ Array<Document> ] The flagged children.
@since 3.0.7
# File lib/mongoid/traversable.rb, line 62 def flag_children_persisted _children.each do |child| child.new_record = false end end
Determines if the document is a subclass of another document.
@example Check if the document is a subclass
Square.new.hereditary?
@return [ true, false ] True if hereditary, false if not.
# File lib/mongoid/traversable.rb, line 74 def hereditary? self.class.hereditary? end
Sets up a child/parent association. This is used for newly created objects so they can be properly added to the graph.
@example Set the parent document.
document.parentize(parent)
@param [ Document ] document The parent document.
@return [ Document ] The parent document.
# File lib/mongoid/traversable.rb, line 87 def parentize(document) self._parent = document end
Remove a child document from this parent. If an embeds one then set to nil, otherwise remove from the embeds many.
This is called from the RemoveEmbedded
persistence command.
@example Remove the child.
document.remove_child(child)
@param [ Document ] child The child (embedded) document to remove.
@since 2.0.0.beta.1
# File lib/mongoid/traversable.rb, line 102 def remove_child(child) name = child.association_name if child.embedded_one? remove_ivar(name) else relation = send(name) relation.send(:delete_one, child) end end
After children are persisted we can call this to move all their changes and flag them as persisted in one call.
@example Reset the children.
document.reset_persisted_children
@return [ Array<Document> ] The children.
@since 2.1.0
# File lib/mongoid/traversable.rb, line 121 def reset_persisted_children _children.each do |child| child.move_changes child.new_record = false end _reset_memoized_children! end