h1. mongoid_tree For our application we need a proper tree structure with Depth-First and Breadth-First searches, parent and child information. Also subtrees need to be exported to JSON. This gem will receive long-term support since we use it in our commercial long-term application. Initially I thought of an embedded solution, but this will only be possible once MongoDB supports embedded collections, and even deep-embedded collections. However this tree is right now on the top of our priority list, means we will put effort into this and release everything in this public gem, as soon as we implement and test it. It will be fully tested with Cucumber and RSpec. h3. Documentation An API Documentation can be found here: "http://rubydoc.info/gems/mongoid_tree/":http://rubydoc.info/gems/mongoid_tree/ h3. Screencasts I've made a screencast demonstrating our tree gem, where I go over the basic methods provided: * "Demo Youtube":http://www.youtube.com/watch?v=TcARGLkBzHw * "Demo screencast.com":http://www.screencast.com/t/N2FlYWFlYz and a "Making Of" screencast, mostly about ruby metaprogramming * "Making Of Youtube":http://www.youtube.com/watch?v=PzjWFrfO7gc * "Making Of screencast.com":http://www.screencast.com/t/M2QxNDY3M h2. Installation Install as Gem gem install mongoid_tree via Gemfile gem 'mongoid_tree', '0.3.3' h2. Usage mongoid_tree can be included as a module

class Category
    include Mongoid::Document
    include Mongoid::Acts::Tree

    field :name
    validates_presence_of :name
end
The following methods and fields are provided: h3. Adding Children I use the _ :references_many, :stored_as => :array_ association Mongoid provides. Association names are fixed to .children and .parent at the moment, but I might make this optional later on.

# Appending a child node
root_node.children << Category.new(:name => "node")

# Inserting a child node before another node
node_2.insert_before(Category.new(:name => "node_1"))

# Inserting a child node after another node
node_2.insert_before(Category.new(:name => "node_3"))
h2. Accessing the Parent Object

node.parent # --> root_node
h2. Deleting Subtrees Just use the usual Association Methods provided by Mongoid. The entire subtree will also be deleted

node.delete
#or
node.destroy
h2. Moving Subtrees You unhinge an entire subtree from it's parent and move it to a new parent. The subtrees path information will automatically be rebuild.

node4.move_to(node_1)
h2. Depth First

File:Depth-first-tree.svg

This is probably your standard call if you want to loop to your tree. E.g. when building a menu. Calling Depth First will return the entire subtree *including* the node you called it on.

root_node.depth_first
#or
root_node.dfs

#returns
[ root_node, child_1, child_1.1, child_2, child_2.1, child_2.2 ]
h2. Breadth First

File:Breadth-first-tree.svg

This is a hardly used option, but hey, why not? Calling Breadth First will return the entire subtree *including* the node you called it on.

root_node.breadth_first
#or
root_node.bfs

#returns
[ root_node, child_1, child_2, child_1.1, child_2.1, child_2.2 ]
h2. Jeweler Standard Text h3. Note on Patches/Pull Requests * Fork the project. * Make your feature addition or bug fix. * Add tests for it. This is important so I don't break it in a future version unintentionally. * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) * Send me a pull request. Bonus points for topic branches. h3. Copyright Used Images are from "Wikipedia":http://commons.wikimedia.org/wiki/Main_Page Copyright (c) 2010 Rainer Kuhn, LittleWebLab.com. See LICENSE for details.