Module: Mongoid::Tree
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/mongoid/tree.rb,
lib/mongoid/tree/ordering.rb,
lib/mongoid/tree/traversal.rb,
lib/mongoid/tree/rational_numbering.rb
Overview
Mongoid::Tree
This module extends any Mongoid document with tree functionality.
Usage
Simply include the module in any Mongoid document:
class Node
include Mongoid::Document
include Mongoid::Tree
end
Using the tree structure
Each document references many children. You can access them using the #children
method.
node = Node.create
node.children.create
node.children.count # => 1
Every document references one parent (unless it’s a root document).
node = Node.create
node.parent # => nil
node.children.create
node.children.first.parent # => node
Destroying
Mongoid::Tree does not handle destroying of nodes by default. However it provides several strategies that help you to deal with children of deleted documents. You can simply add them as before_destroy
callbacks.
Available strategies are:
-
:nullify_children – Sets the children’s parent_id to null
-
:move_children_to_parent – Moves the children to the current document’s parent
-
:destroy_children – Destroys all children by calling their #destroy method (invokes callbacks)
-
:delete_descendants – Deletes all descendants using a database query (doesn’t invoke callbacks)
Example:
class Node
include Mongoid::Document
include Mongoid::Tree
before_destroy :nullify_children
end
Callbacks
Mongoid::Tree offers callbacks for its rearranging process. This enables you to rebuild certain fields when the document was moved in the tree. Rearranging happens before the document is validated. This gives you a chance to validate your additional changes done in your callbacks. See ActiveModel::Callbacks and ActiveSupport::Callbacks for further details on callbacks.
Example:
class Page
include Mongoid::Document
include Mongoid::Tree
after_rearrange :rebuild_path
field :slug
field :path
private
def rebuild_path
self.path = self.ancestors_and_self.collect(&:slug).join('/')
end
end
Defined Under Namespace
Modules: ClassMethods, Ordering, RationalNumbering, Traversal
Class Method Summary collapse
-
.after_rearrange ⇒ undefined
Sets a callback that is called after the document is rearranged.
-
.before_rearrange ⇒ undefined
Sets a callback that is called before the document is rearranged.
Instance Method Summary collapse
-
#ancestor_of?(other) ⇒ Boolean
Is this document an ancestor of the other document?.
-
#ancestors ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s ancestors.
-
#ancestors_and_self ⇒ Array<Mongoid::Document>
Returns an array of this document’s ancestors and itself.
-
#children ⇒ Mongoid::Criteria
Returns a list of the document’s children.
-
#delete_descendants ⇒ void
Deletes all descendants using the database (doesn’t invoke callbacks).
-
#depth ⇒ Fixnum
Returns the depth of this document (number of ancestors).
-
#descendant_of?(other) ⇒ Boolean
Is this document a descendant of the other document?.
-
#descendants ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s descendants.
-
#descendants_and_self ⇒ Array<Mongoid::Document>
Returns and array of this document and it’s descendants.
-
#destroy_children ⇒ void
Destroys all children by calling their #destroy method (does invoke callbacks).
-
#leaf? ⇒ Boolean
Is this document a leaf node (has no children)?.
-
#leaves ⇒ Mongoid::Criteria
Returns all leaves of this document (be careful, currently involves two queries).
-
#move_children_to_parent ⇒ void
Moves all children to this document’s parent.
-
#nullify_children ⇒ void
Nullifies all children’s parent_id.
-
#parent ⇒ Mongoid::Document
Returns the document’s parent (unless it’s a root document).
-
#parent=(document) ⇒ Object
Sets this documents parent document.
-
#parent_ids ⇒ Array<BSON::ObjectId>
Returns a list of the document’s parent_ids, starting with the root node.
-
#rearrange_children! ⇒ void
Forces rearranging of all children after next save.
-
#rearrange_children? ⇒ Boolean
Will the children be rearranged after next save?.
-
#root ⇒ Mongoid::Document
Returns this document’s root node.
-
#root? ⇒ Boolean
Is this document a root node (has no parent)?.
-
#sibling_of?(other) ⇒ Boolean
Is this document a sibling of the other document?.
-
#siblings ⇒ Mongoid::Criteria
Returns this document’s siblings.
-
#siblings_and_self ⇒ Mongoid::Criteria
Returns this document’s siblings and itself.
Class Method Details
.after_rearrange ⇒ undefined
Generated by ActiveSupport
Sets a callback that is called after the document is rearranged
|
# File 'lib/mongoid/tree.rb', line 174
|
.before_rearrange ⇒ undefined
Generated by ActiveSupport
Sets a callback that is called before the document is rearranged
|
# File 'lib/mongoid/tree.rb', line 150
|
Instance Method Details
#ancestor_of?(other) ⇒ Boolean
Is this document an ancestor of the other document?
297 298 299 |
# File 'lib/mongoid/tree.rb', line 297 def ancestor_of?(other) other.parent_ids.include?(self.id) end |
#ancestors ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s ancestors
279 280 281 |
# File 'lib/mongoid/tree.rb', line 279 def ancestors base_class.where(:_id.in => parent_ids).order(:depth => :asc) end |
#ancestors_and_self ⇒ Array<Mongoid::Document>
Returns an array of this document’s ancestors and itself
287 288 289 |
# File 'lib/mongoid/tree.rb', line 287 def ancestors_and_self ancestors + [self] end |
#children ⇒ Mongoid::Criteria
Generated by Mongoid
Returns a list of the document’s children. It’s a references_many
association.
|
# File 'lib/mongoid/tree.rb', line 198
|
#delete_descendants ⇒ void
This method returns an undefined value.
Deletes all descendants using the database (doesn’t invoke callbacks)
403 404 405 |
# File 'lib/mongoid/tree.rb', line 403 def delete_descendants base_class.delete_all(:conditions => { :parent_ids => self.id }) end |
#depth ⇒ Fixnum
Returns the depth of this document (number of ancestors)
254 255 256 |
# File 'lib/mongoid/tree.rb', line 254 def depth super || parent_ids.count end |
#descendant_of?(other) ⇒ Boolean
Is this document a descendant of the other document?
323 324 325 |
# File 'lib/mongoid/tree.rb', line 323 def descendant_of?(other) self.parent_ids.include?(other.id) end |
#descendants ⇒ Mongoid::Criteria
Returns a chainable criteria for this document’s descendants
305 306 307 |
# File 'lib/mongoid/tree.rb', line 305 def descendants base_class.where(:parent_ids => self.id) end |
#descendants_and_self ⇒ Array<Mongoid::Document>
Returns and array of this document and it’s descendants
313 314 315 |
# File 'lib/mongoid/tree.rb', line 313 def descendants_and_self [self] + descendants end |
#destroy_children ⇒ void
This method returns an undefined value.
Destroys all children by calling their #destroy method (does invoke callbacks)
411 412 413 |
# File 'lib/mongoid/tree.rb', line 411 def destroy_children children.destroy_all end |
#leaf? ⇒ Boolean
Is this document a leaf node (has no children)?
242 243 244 |
# File 'lib/mongoid/tree.rb', line 242 def leaf? children.empty? end |
#leaves ⇒ Mongoid::Criteria
Returns all leaves of this document (be careful, currently involves two queries)
357 358 359 |
# File 'lib/mongoid/tree.rb', line 357 def leaves base_class.where(:_id.nin => base_class.only(:parent_id).collect(&:parent_id)).and(:parent_ids => self.id) end |
#move_children_to_parent ⇒ void
This method returns an undefined value.
Moves all children to this document’s parent
392 393 394 395 396 397 |
# File 'lib/mongoid/tree.rb', line 392 def move_children_to_parent children.each do |c| c.parent = self.parent c.save end end |
#nullify_children ⇒ void
This method returns an undefined value.
Nullifies all children’s parent_id
381 382 383 384 385 386 |
# File 'lib/mongoid/tree.rb', line 381 def nullify_children children.each do |c| c.parent = c.parent_id = nil c.save end end |
#parent ⇒ Mongoid::Document
Generated by Mongoid
Returns the document’s parent (unless it’s a root document). It’s a referenced_in
association.
|
# File 'lib/mongoid/tree.rb', line 206
|
#parent=(document) ⇒ Object
Generated by Mongoid
Sets this documents parent document.
|
# File 'lib/mongoid/tree.rb', line 214
|
#parent_ids ⇒ Array<BSON::ObjectId>
Generated by Mongoid
Returns a list of the document’s parent_ids, starting with the root node.
|
# File 'lib/mongoid/tree.rb', line 222
|
#rearrange_children! ⇒ void
This method returns an undefined value.
Forces rearranging of all children after next save
365 366 367 |
# File 'lib/mongoid/tree.rb', line 365 def rearrange_children! @rearrange_children = true end |
#rearrange_children? ⇒ Boolean
Will the children be rearranged after next save?
373 374 375 |
# File 'lib/mongoid/tree.rb', line 373 def rearrange_children? !!@rearrange_children end |
#root ⇒ Mongoid::Document
Returns this document’s root node. Returns ‘self` if the current document is a root node
267 268 269 270 271 272 273 |
# File 'lib/mongoid/tree.rb', line 267 def root if parent_ids.present? base_class.find(parent_ids.first) else self.root? ? self : self.parent.root end end |
#root? ⇒ Boolean
Is this document a root node (has no parent)?
234 235 236 |
# File 'lib/mongoid/tree.rb', line 234 def root? parent_id.nil? end |
#sibling_of?(other) ⇒ Boolean
Is this document a sibling of the other document?
349 350 351 |
# File 'lib/mongoid/tree.rb', line 349 def sibling_of?(other) self.parent_id == other.parent_id end |
#siblings ⇒ Mongoid::Criteria
Returns this document’s siblings
331 332 333 |
# File 'lib/mongoid/tree.rb', line 331 def siblings siblings_and_self.excludes(:id => self.id) end |
#siblings_and_self ⇒ Mongoid::Criteria
Returns this document’s siblings and itself
339 340 341 |
# File 'lib/mongoid/tree.rb', line 339 def siblings_and_self base_class.where(:parent_id => self.parent_id) end |