A tree structure for Mongoid documents using the materialized path pattern
-
mongoid (>= 2.0.0.beta.17)
To install mongoid_tree, simply add it to your Gemfile:
gem 'mongoid-tree', :require => 'mongoid/tree'
In order to get the latest development version of mongoid-tree:
gem 'mongoid-tree', :git => 'git://github.com/benedikt/mongoid-tree', :require => 'mongoid/tree'
You might want to remove the :require => 'mongoid/tree'
option and explicitly require 'mongoid/tree'
where needed and finally run
bundle install
Read the API documentation at benedikt.github.com/mongoid-tree and take a look at the Mongoid::Tree module
require 'mongoid/tree' class Node include Mongoid::Document include Mongoid::Tree end
There are several utility methods that help getting to other related documents in the tree:
Node.root Node.roots Node.leaves node.root node.parent node.children node.ancestors node.ancestors_and_self node.descendants node.descendants_and_self node.siblings node.siblings_and_self node.leaves node.lower_items (siblings) node.higher_items (siblings) node.first_item_in_list (first sibling) node.last_item_in_list (last sibling)
Siblings are ordered, and there are a few utility methods for managing their position in the list:
node.move_above(other) node.move_below(other) node.move_to_top node.mode_to_bottom
In addition it’s possible to check certain aspects of the document’s position in the tree:
node.root? node.leaf? node.depth node.ancestor_of?(other) node.descendant_of?(other) node.at_top? node.at_bottom?
See Mongoid::Tree for more information on these methods.
It’s possible to traverse the tree using different traversal methods. See Mongoid::Tree::Traversal for details
node.traverse(:breadth_first) do |n| # Do something with Node n end
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
There are two callbacks that are called before and after the rearranging process. This enables you to do additional computations after the documents position in the tree is updated. See Mongoid::Tree for details.
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
See github.com/benedikt/mongoid-tree/issues
See github.com/benedikt/mongoid-tree and feel free to fork it!
Copyright © 2010 Benedikt Deicke. See LICENSE for details.