Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 319 lines (241 sloc) 19.247 kB
79671c4 @stefankroes Started on rdoc readme
stefankroes authored
1 = Ancestry
1282d2e @stefankroes Initial commit
stefankroes authored
2
f1955bb @stefankroes Changed test suite to run independently of Rails application
stefankroes authored
3 Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are STI support, scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.
1282d2e @stefankroes Initial commit
stefankroes authored
4
79671c4 @stefankroes Started on rdoc readme
stefankroes authored
5 = Installation
1282d2e @stefankroes Initial commit
stefankroes authored
6
7 To apply Ancestry to any ActiveRecord model, follow these simple steps:
8
f9c0143 @stefankroes Changed README on installation
stefankroes authored
9 1. Install
10 - <b>Rails 2</b>
11 - Add to config/environment.rb: <b>config.gem 'ancestry'</b>
12 - Install required gems: <b>sudo rake gems:install</b>
13 - <b>Rails 3</b>
14 - Add to Gemfile: <b>gem 'ancestry'</b>
15 - Install required gems: <b>bundle install</b>
1282d2e @stefankroes Initial commit
stefankroes authored
16
22a1984 - Added some tests for node creation through scopes
Stefan Kroes authored
17 2. Add ancestry column to your table
e1c95c7 Changed generate commands in README to Rails 3 syntax
Stefan Kroes authored
18 - Create migration: <b>rails g migration add_ancestry_to_[table] ancestry:string</b>
90c4a10 @stefankroes Updated README
stefankroes authored
19 - Add index to migration: <b>add_index [table], :ancestry</b> (UP) / <b>remove_index [table], :ancestry</b> (DOWN)
20 - Migrate your database: <b>rake db:migrate</b>
1282d2e @stefankroes Initial commit
stefankroes authored
21
22a1984 - Added some tests for node creation through scopes
Stefan Kroes authored
22 3. Add ancestry to your model
ecea76f @stefankroes Version 1.2.0
stefankroes authored
23 - Add to app/models/[model].rb: <b>has_ancestry</b>
1282d2e @stefankroes Initial commit
stefankroes authored
24
25 Your model is now a tree!
26
ecea76f @stefankroes Version 1.2.0
stefankroes authored
27 = Using acts_as_tree instead of has_ancestry
28
29 In version 1.2.0 the <b>acts_as_tree</b> method was <b>renamed to has_ancestry</b> in order to allow usage of both the acts_as_tree gem and the ancestry gem in a single application. To not break backwards compatibility, the has_ancestry method is aliased with acts_as_tree if ActiveRecord::Base does not respond to acts_as_tree. acts_as_tree will continue to be supported in the future as I personally prefer it.
30
41c344d @stefankroes Updated readme
stefankroes authored
31 = Organising records into a tree
1282d2e @stefankroes Initial commit
stefankroes authored
32
33 You can use the parent attribute to organise your records into a tree. If you have the id of the record you want to use as a parent and don't want to fetch it, you can also use parent_id. Like any virtual model attributes, parent and parent_id can be set using parent= and parent_id= on a record or by including them in the hash passed to new, create, create!, update_attributes and update_attributes!. For example:
34
95e6701 @stefankroes Updated README
stefankroes authored
35 TreeNode.create! :name => 'Stinky', :parent => TreeNode.create!(:name => 'Squeeky')
1282d2e @stefankroes Initial commit
stefankroes authored
36
48d00be @stefankroes Updated readme
stefankroes authored
37 You can also create children through the children relation on a node:
38
95e6701 @stefankroes Updated README
stefankroes authored
39 node.children.create :name => 'Stinky'
48d00be @stefankroes Updated readme
stefankroes authored
40
41c344d @stefankroes Updated readme
stefankroes authored
41 = Navigating your tree
1282d2e @stefankroes Initial commit
stefankroes authored
42
43 To navigate an Ancestry model, use the following methods on any instance / record:
44
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
45 parent Returns the parent of the record, nil for a root node
46 parent_id Returns the id of the parent of the record, nil for a root node
47 root Returns the root of the tree the record is in, self for a root node
48 root_id Returns the id of the root of the tree the record is in
49 is_root? Returns true if the record is a root node, false otherwise
50 ancestor_ids Returns a list of ancestor ids, starting with the root id and ending with the parent id
51 ancestors Scopes the model on ancestors of the record
22c43f4 @stefankroes Fixed to typos and changed date in gemspec
stefankroes authored
52 path_ids Returns a list the path ids, starting with the root id and ending with the node's own id
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
53 path Scopes model on path records of the record
54 children Scopes the model on children of the record
55 child_ids Returns a list of child ids
56 has_children? Returns true if the record has any children, false otherwise
57 is_childless? Returns true is the record has no childen, false otherwise
58 siblings Scopes the model on siblings of the record, the record itself is included
59 sibling_ids Returns a list of sibling ids
60 has_siblings? Returns true if the record's parent has more than one child
61 is_only_child? Returns true if the record is the only child of its parent
62 descendants Scopes the model on direct and indirect children of the record
63 descendant_ids Returns a list of a descendant ids
64 subtree Scopes the model on descendants and itself
65 subtree_ids Returns a list of all ids in the record's subtree
66 depth Return the depth of the node, root nodes are at depth 0
67
ecea76f @stefankroes Version 1.2.0
stefankroes authored
68 = Options for has_ancestry
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
69
ecea76f @stefankroes Version 1.2.0
stefankroes authored
70 The has_ancestry methods supports the following options:
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
71
72 :ancestry_column Pass in a symbol to store ancestry in a different column
73 :orphan_strategy Instruct Ancestry what to do with children of a node that is destroyed:
74 :destroy All children are destroyed as well (default)
75 :rootify The children of the destroyed node become root nodes
76 :restrict An AncestryException is raised if any children exist
26a0bc9 changed the readme file
unknown authored
77 :adopt The orphan subtree is added to the parent of the deleted node.If the deleted node is Root, then rootify the orphan subtree.
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
78 :cache_depth Cache the depth of each node in the 'ancestry_depth' column (default: false)
e3ea26a @stefankroes - Version 1.1.2 (2009-10-29)
stefankroes authored
79 If you turn depth_caching on for an existing model:
ad6dda9 @dburrows amended cache depth migration
dburrows authored
80 - Migrate: add_column [table], :ancestry_depth, :integer, :default => 0
e3ea26a @stefankroes - Version 1.1.2 (2009-10-29)
stefankroes authored
81 - Build cache: TreeNode.rebuild_depth_cache!
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
82 :depth_cache_column Pass in a symbol to store depth cache in a different column
c410dcf Documentation for :primary_key_format.
Rolf Timmermans authored
83 :primary_key_format Supply a regular expression that matches the format of your primary key.
84 By default, primary keys only match integers ([0-9]+).
1282d2e @stefankroes Initial commit
stefankroes authored
85
22a1984 - Added some tests for node creation through scopes
Stefan Kroes authored
86 = (Named) Scopes
1282d2e @stefankroes Initial commit
stefankroes authored
87
88 Where possible, the navigation methods return scopes instead of records, this means additional ordering, conditions, limits, etc. can be applied and that the result can be either retrieved, counted or checked for existence. For example:
89
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
90 node.children.exists?(:name => 'Mary')
91 node.subtree.all(:order => :name, :limit => 10).each do; ...; end
92 node.descendants.count
1282d2e @stefankroes Initial commit
stefankroes authored
93
22a1984 - Added some tests for node creation through scopes
Stefan Kroes authored
94 For convenience, a couple of named scopes are included at the class level:
1282d2e @stefankroes Initial commit
stefankroes authored
95
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
96 roots Root nodes
97 ancestors_of(node) Ancestors of node, node can be either a record or an id
98 children_of(node) Children of node, node can be either a record or an id
99 descendants_of(node) Descendants of node, node can be either a record or an id
ecea76f @stefankroes Version 1.2.0
stefankroes authored
100 subtree_of(node) Subtree of node, node can be either a record or an id
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
101 siblings_of(node) Siblings of node, node can be either a record or an id
1282d2e @stefankroes Initial commit
stefankroes authored
102
22a1984 - Added some tests for node creation through scopes
Stefan Kroes authored
103 Thanks to some convenient rails magic, it is even possible to create nodes through the children and siblings scopes:
104
48d00be @stefankroes Updated readme
stefankroes authored
105 node.children.create
106 node.siblings.create!
107 TestNode.children_of(node_id).new
108 TestNode.siblings_of(node_id).create
1282d2e @stefankroes Initial commit
stefankroes authored
109
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
110 = Selecting nodes by depth
1282d2e @stefankroes Initial commit
stefankroes authored
111
ecea76f @stefankroes Version 1.2.0
stefankroes authored
112 When depth caching is enabled (see has_ancestry options), five more named scopes can be used to select nodes on their depth:
1282d2e @stefankroes Initial commit
stefankroes authored
113
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
114 before_depth(depth) Return nodes that are less deep than depth (node.depth < depth)
115 to_depth(depth) Return nodes up to a certain depth (node.depth <= depth)
116 at_depth(depth) Return nodes that are at depth (node.depth == depth)
117 from_depth(depth) Return nodes starting from a certain depth (node.depth >= depth)
118 after_depth(depth) Return nodes that are deeper than depth (node.depth > depth)
119
120 The depth scopes are also available through calls to descendants, descendant_ids, subtree, subtree_ids, path and ancestors. In this case, depth values are interpreted relatively. Some examples:
121
122 node.subtree(:to_depth => 2) Subtree of node, to a depth of node.depth + 2 (self, children and grandchildren)
123 node.subtree.to_depth(5) Subtree of node to an absolute depth of 5
124 node.descendants(:at_depth => 2) Descendant of node, at depth node.depth + 2 (grandchildren)
125 node.descendants.at_depth(10) Descendants of node at an absolute depth of 10
126 node.ancestors.to_depth(3) The oldest 4 ancestors of node (its root and 3 more)
127 node.path(:from_depth => -2) The node's grandparent, parent and the node itself
128
129 node.ancestors(:from_depth => -6, :to_depth => -4)
130 node.path.from_depth(3).to_depth(4)
131 node.descendants(:from_depth => 2, :to_depth => 4)
132 node.subtree.from_depth(10).to_depth(12)
133
134 Please note that depth constraints cannot be passed to ancestor_ids and path_ids. The reason for this is that both these relations can be fetched directly from the ancestry column without performing a database query. It would require an entirely different method of applying the depth constraints which isn't worth the effort of implementing. You can use ancestors(depth_options).map(&:id) or ancestor_ids.slice(min_depth..max_depth) instead.
1282d2e @stefankroes Initial commit
stefankroes authored
135
e3ea26a @stefankroes - Version 1.1.2 (2009-10-29)
stefankroes authored
136 = STI support
137
138 Ancestry works fine with STI. Just create a STI inheritance hierarchy and build an Ancestry tree from the different classes/models. All Ancestry relations that where described above will return nodes of any model type. If you do only want nodes of a specific subclass you'll have to add a condition on type for that.
139
79671c4 @stefankroes Started on rdoc readme
stefankroes authored
140 = Arrangement
1282d2e @stefankroes Initial commit
stefankroes authored
141
142 Ancestry can arrange an entire subtree into nested hashes for easy navigation after retrieval from the database. TreeNode.arrange could for example return:
143
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
144 { #<TreeNode id: 100018, name: "Stinky", ancestry: nil>
145 => { #<TreeNode id: 100019, name: "Crunchy", ancestry: "100018">
146 => { #<TreeNode id: 100020, name: "Squeeky", ancestry: "100018/100019">
147 => {}
148 }
1282d2e @stefankroes Initial commit
stefankroes authored
149 }
150 }
151
152 The arrange method also works on a scoped class, for example:
153
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
154 TreeNode.find_by_name('Crunchy').subtree.arrange
1282d2e @stefankroes Initial commit
stefankroes authored
155
59d155e Fixed little mistake in README about arrangement
Stefan Kroes authored
156 The arrange method takes ActiveRecord find options. If you want your hashes to be ordered, you should pass the order to the arrange method instead of to the scope. This also works for Ruby 1.8 since an OrderedHash is returned. For example:
ecea76f @stefankroes Version 1.2.0
stefankroes authored
157
158 TreeNode.find_by_name('Crunchy').subtree.arrange(:order => :name)
159
adb9acd @kueda Documented the sort_by_ancestry method in the README.
kueda authored
160 = Sorting
161
162 If you just want to sort an array of nodes as if you were traversing them in preorder, you can use the sort_by_ancestry class method:
163
164 TreeNode.sort_by_ancestry(array_of_nodes)
165
166 Note that since materialised path trees don't support ordering within a rank, the order of siblings depends on their order in the original array.
167
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
168 = Migrating from plugin that uses parent_id column
169
ecea76f @stefankroes Version 1.2.0
stefankroes authored
170 Most current tree plugins use a parent_id column (has_ancestry, awesome_nested_set, better_nested_set, acts_as_nested_set). With ancestry its easy to migrate from any of these plugins, to do so, use the build_ancestry_from_parent_ids! method on your ancestry model. These steps provide a more detailed explanation:
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
171
172 1. Add ancestry column to your table
e1c95c7 Changed generate commands in README to Rails 3 syntax
Stefan Kroes authored
173 - Create migration: <b>rails g migration add_ancestry_to_[table] ancestry:string</b>
90c4a10 @stefankroes Updated README
stefankroes authored
174 - Add index to migration: <b>add_index [table], :ancestry</b> (UP) / <b>remove_index [table], :ancestry</b> (DOWN)
175 - Migrate your database: <b>rake db:migrate</b>
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
176
177 2. Remove old tree plugin or gem and add in Ancestry
178 - Remove plugin: rm -Rf vendor/plugins/[old plugin]
179 - Remove gem config line from environment.rb: config.gem [old gem]
180 - Add Ancestry to environment.rb: config.gem :ancestry
181 - See 'Installation' for more info on installing and configuring gems
182
183 3. Change your model
184 - Remove any macros required by old plugin/gem from app/models/[model].rb
ecea76f @stefankroes Version 1.2.0
stefankroes authored
185 - Add to app/models/[model].rb: <b>has_ancestry</b>
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
186
90c4a10 @stefankroes Updated README
stefankroes authored
187 4. Generate ancestry columns
188 - In './script.console': <b>[model].build_ancestry_from_parent_ids!</b>
189 - Make sure it worked ok: <b>[model].check_ancestry_integrity!</b>
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
190
191 5. Change your code
192 - Most tree calls will probably work fine with ancestry
193 - Others must be changed or proxied
194 - Check if all your data is intact and all tests pass
195
196 6. Drop parent_id column:
e1c95c7 Changed generate commands in README to Rails 3 syntax
Stefan Kroes authored
197 - Create migration: <b>rails g migration remove_parent_id_from_[table]</b>
90c4a10 @stefankroes Updated README
stefankroes authored
198 - Add to migration: <b>remove_column [table], :parent_id</b> (UP) / <b>add_column [table], :parent_id, :integer</b> (DOWN)
199 - Migrate your database: <b>rake db:migrate</b>
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
200
41c344d @stefankroes Updated readme
stefankroes authored
201 = Integrity checking and restoration
1282d2e @stefankroes Initial commit
stefankroes authored
202
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
203 I don't see any way Ancestry tree integrity could get compromised without explicitly setting cyclic parents or invalid ancestry and circumventing validation with update_attribute, if you do, please let me know.
204
648a79c @stefankroes Fixed README and gemspec
stefankroes authored
205 Ancestry includes some methods for detecting integrity problems and restoring integrity just to be sure. To check integrity use: [Model].check_ancestry_integrity!. An AncestryIntegrityException will be raised if there are any problems. You can also specify :report => :list to return an array of exceptions or :report => :echo to echo any error messages. To restore integrity use: [Model].restore_ancestry_integrity!.
1282d2e @stefankroes Initial commit
stefankroes authored
206
207 For example, from IRB:
208
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
209 >> stinky = TreeNode.create :name => 'Stinky'
d43ece5 @stefankroes Some last changes to the readme
stefankroes authored
210 $ #<TreeNode id: 1, name: "Stinky", ancestry: nil>
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
211 >> squeeky = TreeNode.create :name => 'Squeeky', :parent => stinky
d43ece5 @stefankroes Some last changes to the readme
stefankroes authored
212 $ #<TreeNode id: 2, name: "Squeeky", ancestry: "1">
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
213 >> stinky.update_attribute :parent, squeeky
d43ece5 @stefankroes Some last changes to the readme
stefankroes authored
214 $ true
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
215 >> TreeNode.all
d43ece5 @stefankroes Some last changes to the readme
stefankroes authored
216 $ [#<TreeNode id: 1, name: "Stinky", ancestry: "1/2">, #<TreeNode id: 2, name: "Squeeky", ancestry: "1/2/1">]
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
217 >> TreeNode.check_ancestry_integrity!
8d2cffb @stefankroes Fixed some problems in the README
stefankroes authored
218 !! Ancestry::AncestryIntegrityException: Conflicting parent id in node 1: 2 for node 1, expecting nil
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
219 >> TreeNode.restore_ancestry_integrity!
d43ece5 @stefankroes Some last changes to the readme
stefankroes authored
220 $ [#<TreeNode id: 1, name: "Stinky", ancestry: 2>, #<TreeNode id: 2, name: "Squeeky", ancestry: nil>]
1282d2e @stefankroes Initial commit
stefankroes authored
221
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
222 Additionally, if you think something is wrong with your depth cache:
223
224 >> TreeNode.rebuild_depth_cache!
1282d2e @stefankroes Initial commit
stefankroes authored
225
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
226 = Tests
227
648a79c @stefankroes Fixed README and gemspec
stefankroes authored
228 The Ancestry gem comes with a unit test suite consisting of about 1800 assertions in about 30 tests. It takes about 10 seconds to run on sqlite. To run it yourself check out the repository from GitHub, copy test/database.example.yml to test/database.yml and type 'rake'. You can pass rake style options for ActiveRecord version to test against (e.g. ar=3.0.1) and database to test against (e.g. db=mysql). The test suite is located in test/has_ancestry_test.rb.
1282d2e @stefankroes Initial commit
stefankroes authored
229
79671c4 @stefankroes Started on rdoc readme
stefankroes authored
230 = Internals
1282d2e @stefankroes Initial commit
stefankroes authored
231
232 As can be seen in the previous section, Ancestry stores a path from the root to the parent for every node. This is a variation on the materialised path database pattern. It allows Ancestry to fetch any relation (siblings, descendants, etc.) in a single sql query without the complicated algorithms and incomprehensibility associated with left and right values. Additionally, any inserts, deletes and updates only affect nodes within the affected node's own subtree.
233
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
234 In the example above, the ancestry column is created as a string. This puts a limitation on the depth of the tree of about 40 or 50 levels, which I think may be enough for most users. To increase the maximum depth of the tree, increase the size of the string that is being used or change it to a text to remove the limitation entirely. Changing it to a text will however decrease performance because an index cannot be put on the column in that case.
235
236 The materialised path pattern requires Ancestry to use a 'like' condition in order to fetch descendants. This should not be particularly slow however since the the condition never starts with a wildcard which allows the DBMS to use the column index. If you have any data on performance with a large number of records, please drop me line.
237
238 = Version history
239
d259c87 Removed latest version from paragraph because I always forget to upda…
Stefan Kroes authored
240 The latest version of ancestry is recommended. The three numbers of each version numbers are respectively the major, minor and patch versions. We started with major version 1 because it looks so much better and ancestry was already quite mature and complete when it was published. The major version is only bumped when backwards compatibility is broken. The minor version is bumped when new features are added. The patch version is bumped when bugs are fixed.
ecea76f @stefankroes Version 1.2.0
stefankroes authored
241
59d155e Fixed little mistake in README about arrangement
Stefan Kroes authored
242 - Version 1.2.4 (2011-4-22)
243 - Prepended table names to column names in queries (thx raelik)
244 - Better check to see if acts_as_tree can be overloaded (thx jims)
245 - Performance inprovements (thx kueda)
9267b46 Released 1.2.3
Stefan Kroes authored
246 - Version 1.2.3 (2010-10-28)
247 - Fixed error with determining ActiveRecord version
248 - Added option to specify :primary_key_format (thanks goes to rolftimmermans)
e84fa5e @stefankroes Ancestry 1.2.2
stefankroes authored
249 - Version 1.2.2 (2010-10-24)
648a79c @stefankroes Fixed README and gemspec
stefankroes authored
250 - Fixed all deprecation warnings for rails 3.0.X
251 - Added :report option to check_ancestry_integrity!
252 - Changed ActiveRecord dependency to 2.2.2
253 - Tested and fixed for ruby 1.8.7 and 1.9.2
e84fa5e @stefankroes Ancestry 1.2.2
stefankroes authored
254 - Changed usage of update_attributes to update_attribute to allow ancestry column protection
ecea76f @stefankroes Version 1.2.0
stefankroes authored
255 - Version 1.2.0 (2009-11-07)
256 - Removed some duplication in has_ancestry
257 - Cleaned up plugin pattern according to http://yehudakatz.com/2009/11/12/better-ruby-idioms/
258 - Moved parts of ancestry into seperate files
259 - Made it possible to pass options into the arrange method
260 - Renamed acts_as_tree to has_ancestry
261 - Aliased has_ancestry as acts_as_tree if acts_as_tree is available
262 - Added subtree_of scope
263 - Updated ordered_by_ancestry scope to support Microsoft SQL Server
264 - Added empty hash as parameter to exists? calls for older ActiveRecord versions
853e453 @stefankroes - Version 1.1.4 (2009-11-07)
stefankroes authored
265 - Version 1.1.4 (2009-11-07)
266 - Thanks to a patch from tom taylor, Ancestry now works with different primary keys
b9a102a @stefankroes - Version 1.1.3 (2009-11-01)
stefankroes authored
267 - Version 1.1.3 (2009-11-01)
268 - Fixed a pretty bad bug where several operations took far too many queries
e3ea26a @stefankroes - Version 1.1.2 (2009-10-29)
stefankroes authored
269 - Version 1.1.2 (2009-10-29)
270 - Added validation for depth cache column
271 - Added STI support (reported broken)
48441fb @stefankroes - Version 1.1.1 (2009-10-28)
stefankroes authored
272 - Version 1.1.1 (2009-10-28)
273 - Fixed some parentheses warnings that where reported
274 - Fixed a reported issue with arrangement
275 - Fixed issues with ancestors and path order on postgres
276 - Added ordered_by_ancestry scope (needed to fix issues)
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
277 - Version 1.1.0 (2009-10-22)
278 - Depth caching (and cache rebuilding)
279 - Depth method for nodes
280 - Named scopes for selecting by depth
281 - Relative depth options for tree navigation methods:
282 - ancestors
283 - path
284 - descendants
285 - descendant_ids
286 - subtree
287 - subtree_ids
288 - Updated README
289 - Easy migration from existing plugins/gems
290 - acts_as_tree checks unknown options
291 - acts_as_tree checks that options are hash
292 - Added a bang (!) to the integrity functions
ecea76f @stefankroes Version 1.2.0
stefankroes authored
293 - Since these functions should only be used from ./script/console and not from your application, this change is not considered as breaking backwards compatibility and the major version wasn't bumped.
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
294 - Updated install script to point to documentation
295 - Removed rails specific init
296 - Removed uninstall script
297 - Version 1.0.0 (2009-10-16)
298 - Initial version
299 - Tree building
300 - Tree navigation
301 - Integrity checking / restoration
302 - Arrangement
303 - Orphan strategies
304 - Subtree movement
305 - Named scopes
306 - Validations
1282d2e @stefankroes Initial commit
stefankroes authored
307
41c344d @stefankroes Updated readme
stefankroes authored
308 = Future work
1282d2e @stefankroes Initial commit
stefankroes authored
309
df705c3 @stefankroes Version 1.1.0 done!
stefankroes authored
310 I will try to keep Ancestry up to date with changing versions of Rails and Ruby and also with any bug reports I might receive. I will implement new features on request as I see fit. One thing I definitely want to do soon is some proper performance testing.
1282d2e @stefankroes Initial commit
stefankroes authored
311
41c344d @stefankroes Updated readme
stefankroes authored
312 = Contact and copyright
1282d2e @stefankroes Initial commit
stefankroes authored
313
41c344d @stefankroes Updated readme
stefankroes authored
314 Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on 'http://github.com/stefankroes/ancestry/issues'. Please also contact me at s.a.kroes[at]gmail.com if it's urgent.
315
31ad369 @stefankroes Deleted IRC channel from README
stefankroes authored
316 Question? Contact me at s.a.kroes[at]gmail.com, make sure you read the documentation.
1282d2e @stefankroes Initial commit
stefankroes authored
317
318 Copyright (c) 2009 Stefan Kroes, released under the MIT license
Something went wrong with that request. Please try again.