You are here: Browse Railsplugins Better Nested Set
= Better nested set
This plugin provides an ehanced acts_as_nested_set mixin for ActiveRecord, the object-db mapping layer of the framework RubyOnRails. The original nested set feature seems to be quite old and missed some necessary functionalities.
DetailsThis acts provides Nested Set functionality. Nested Set is a smart way to implement an ordered tree, with the added feature that you can select the children and all of their descendents with a single query. The drawback is that insertion or move need some complex sql queries. But everything is done behind the curtains by this module!
Nested sets are appropriate each time you want either an orderd tree (menus, commercial categories) or an efficient way of querying big trees (threaded posts).
See http://www.dbmsmag.com/9603d06.html for nested sets theory, and a tutorial here: http://threebit.net/tutorials/nestedset/tutorial1.html
Small nested set theory reminderInstead of picturing a leaf node structure with children pointing back to their parent, the best way to imagine how this works is to think of the parent entity surrounding all of its children, and its parent surrounding it, etc. Assuming that they are lined up horizontally, we store the left and right boundries in the database.
Imagine: root |_ Child 1 |_ Child 1.1 |_ Child 1.2 |_ Child 2 |_ Child 2.1 |_ Child 2.2
If my cirlces in circles description didn’t make sense, check out this sweet ASCII art:
| Root | |||
| _____ _____ | |||
| Child 1 | Child 2 | ||
| __ _ | __ _ | ||
| C 1.1 | C 1.2 | C 2.1 | C 2.2 |
| 1 2 3__4 5_6 7 8 9___10 11___12 13 14 | _____ | _____ | |
|---|---|---|---|
| ___________ |
The numbers represent the left and right boundries. The table then might look like this: id | parent_is | left | right | data 1 | | 1 | 14 | root 2 | 1 | 2 | 7 | Child 1 3 | 2 | 3 | 4 | Child 1.1 4 | 2 | 5 | 6 | Child 1.2 5 | 1 | 8 | 13 | Child 2 6 | 5 | 9 | 10 | Child 2.1 7 | 5 | 11 | 12 | Child 2.2
So, to get all children of an entry ‘parent’, you SELECT * WHERE left IS BETWEEN parent.left AND parent.right
To get the count, it’s (right – left – 1)/2, etc. To get the direct parent, it falls back to using the parent_id field. There are instance methods for all of these.
= API
Methods names are aligned on Tree’s ones as much as possible, to make replacment from one by another easier, except for the creation:
in acts_as_tree:
item.children.create(:name => "child1")
in acts_as_nested_set:
== Recommandation
Don’t name your left and right columns ‘left’ and ‘right’: these names are reserved on most of dbs. Usage is to name them ‘lft’ and ‘rgt’ for instance.
= Where to find better_nested_set
This plugin is provided by Jean-Christophe Michel from Symétrie, and is available on
http://opensource.symetrie.com/trac/better_nested_set/
Subversion repository is on
http://opensource.symetrie.com/svn/better_nested_set/trunk
= License
Copyright© 2006 Jean-Christophe Michel, Symétrie
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
NOTE: This description has been extracted from the Plugin README and so the formatting may need updating to make browser friendly