root/trunk/README

Revision 3, 6.0 kB (checked in by jcm, 2 years ago)

repository url added in README

Line 
1 = Better nested set
2
3 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.
4
5 == Details
6
7 This acts provides Nested Set functionality. Nested Set is a smart way to implement
8 an _ordered_ tree, with the added feature that you can select the children and all of their
9 descendents with a single query. The drawback is that insertion or move need some complex
10 sql queries. But everything is done behind the curtains by this module!
11
12 Nested sets are appropriate each time you want either an orderd tree (menus,
13 commercial categories) or an efficient way of querying big trees (threaded posts).
14
15 See http://www.dbmsmag.com/9603d06.html for nested sets theory, and a tutorial here:
16 http://threebit.net/tutorials/nestedset/tutorial1.html
17
18 == Small nested set theory reminder
19
20 Instead of picturing a leaf node structure with children pointing back to their parent,
21 the best way to imagine how this works is to think of the parent entity surrounding all
22 of its children, and its parent surrounding it, etc.  Assuming that they are lined up
23 horizontally, we store the left and right boundries in the database.
24
25 Imagine:
26   root
27     |_ Child 1
28       |_ Child 1.1
29       |_ Child 1.2
30     |_ Child 2
31       |_ Child 2.1
32       |_ Child 2.2
33
34 If my cirlces in circles description didn't make sense, check out this sweet
35 ASCII art:
36
37     ___________________________________________________________________
38    |  Root                                                             |
39    |    ____________________________    ____________________________   |
40    |   |  Child 1                  |   |  Child 2                  |   |
41    |   |   __________   _________  |   |   __________   _________  |   |
42    |   |  |  C 1.1  |  |  C 1.2 |  |   |  |  C 2.1  |  |  C 2.2 |  |   |
43    1   2  3_________4  5________6  7   8  9_________10 11_______12 13  14
44    |   |___________________________|   |___________________________|   |
45    |___________________________________________________________________|
46
47 The numbers represent the left and right boundries.  The table then might
48 look like this:
49    id | parent_is | left | right | data
50     1 |           |    1 |    14 | root
51     2 |         1 |    2 |     7 | Child 1
52     3 |         2 |    3 |     4 | Child 1.1
53     4 |         2 |    5 |     6 | Child 1.2
54     5 |         1 |    8 |    13 | Child 2
55     6 |         5 |    9 |    10 | Child 2.1
56     7 |         5 |   11 |    12 | Child 2.2
57
58 So, to get all children of an entry 'parent', you
59     SELECT * WHERE left IS BETWEEN parent.left AND parent.right
60
61 To get the count, it's (right - left - 1)/2, etc.
62 To get the direct parent, it falls back to using the parent_id field.   
63 There are instance methods for all of these.
64
65
66 = API
67
68 Methods names are aligned on Tree's ones as much as possible, to make replacment from one
69 by another easier, except for the creation:
70
71 in acts_as_tree:
72
73   item.children.create(:name => "child1")
74
75 in acts_as_nested_set:
76
77   # adds a new item at the "end" of the tree, i.e. with child.left = max(tree.right)+1
78   child = MyClass.new(:name => "child1")
79   child.save
80   # now move the item to its right place
81   child.move_to_child_of my_item
82
83 You can use:
84 * <tt>move_to_child_of</tt>
85 * <tt>move_to_right_of</tt>
86 * <tt>move_to_left_of</tt>
87 and pass them an id or an object.
88
89 Other methods added by this mixin are:
90 * <tt>root</tt> - root item of the tree (the one that has a nil parent; should have left_column = 1 too)
91 * <tt>roots</tt> - root items, in case of multiple roots (the ones that have a nil parent)
92 * <tt>level</tt> - number indicating the level, a root being level 0
93 * <tt>ancestors</tt> - array of all parents, with root as first item
94 * <tt>self_and_ancestors</tt> - array of all parents and self
95 * <tt>siblings</tt> - array of all siblings, that are the items sharing the same parent and level
96 * <tt>self_and_siblings</tt> - array of itself and all siblings
97 * <tt>children_count</tt> - count of all immediate children
98 * <tt>children</tt> - array of all immediate childrens
99 * <tt>all_children</tt> - array of all children and nested children
100 * <tt>full_set</tt> - array of itself and all children and nested children
101
102 These should not be useful, except if you want to write direct SQL:
103 * <tt>left_col_name</tt> - name of the left column passed on the declaration line
104 * <tt>right_col_name</tt> - name of the right column passed on the declaration line   
105 * <tt>parent_col_name</tt> - name of the parent column passed on the declaration line
106
107 == Recommandation
108
109 Don't name your left and right columns 'left' and 'right': these names are reserved on most of dbs.
110 Usage is to name them 'lft' and 'rgt' for instance.
111
112 = Where to find better_nested_set
113
114 This plugin is provided by Jean-Christophe Michel from Symétrie, and is available on
115
116   http://opensource.symetrie.com/trac/better_nested_set/
117  
118 Subversion repository is on
119
120   http://opensource.symetrie.com/svn/better_nested_set/trunk
121
122 = License
123
124 Copyright (c) 2006 Jean-Christophe Michel, Symétrie
125
126 The MIT License
127
128 Permission is hereby granted, free of charge, to any person obtaining a copy
129 of this software and associated documentation files (the "Software"), to deal
130 in the Software without restriction, including without limitation the rights
131 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
132 copies of the Software, and to permit persons to whom the Software is
133 furnished to do so, subject to the following conditions:
134
135 The above copyright notice and this permission notice shall be included in
136 all copies or substantial portions of the Software.
137
138 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
139 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
140 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
141 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
142 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
143 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
144 THE SOFTWARE
Note: See TracBrowser for help on using the browser.