README.md in closure_tree-3.0.0 vs README.md in closure_tree-3.0.1

- old
+ new

@@ -1,18 +1,19 @@ # Closure Tree Closure Tree is a mostly-API-compatible replacement for the acts_as_tree and awesome_nested_set gems, but with much better -mutation performance thanks to the Closure Tree storage algorithm. +mutation performance thanks to the Closure Tree storage algorithm, +as well as support for polymorphism within the hierarchy. See [Bill Karwin](http://karwin.blogspot.com/)'s excellent [Models for hierarchical data presentation](http://www.slideshare.net/billkarwin/models-for-hierarchical-data) for a description of different tree storage algorithms. ## Setup -Note that closure_tree is being developed for Rails 3.1.x +Note that closure_tree supports Rails 3. Rails 2, not so much. 1. Add this to your Gemfile: ```gem 'closure_tree'``` 2. Run ```bundle install``` @@ -20,39 +21,39 @@ 4. Add a migration to add a ```parent_id``` column to the model you want to act_as_tree. Note that if the column is null, the tag will be considered a root node. - ```ruby - class AddParentIdToTag < ActiveRecord::Migration - def change - add_column :tag, :parent_id, :integer - end + ```ruby + class AddParentIdToTag < ActiveRecord::Migration + def change + add_column :tag, :parent_id, :integer end - ``` + end + ``` 5. Add a database migration to store the hierarchy for your model. By convention the table name will be the model's table name, followed by "_hierarchy". Note that by calling ```acts_as_tree```, a "virtual model" (in this case, ```TagsHierarchy```) will be added automatically, so you don't need to create it. - ```ruby - class CreateTagHierarchies < ActiveRecord::Migration - def change - create_table :tag_hierarchies, :id => false do |t| - t.integer :ancestor_id, :null => false # ID of the parent/grandparent/great-grandparent/... tag - t.integer :descendant_id, :null => false # ID of the target tag - t.integer :generations, :null => false # Number of generations between the ancestor and the descendant. Parent/child = 1, for example. - end + ```ruby + class CreateTagHierarchies < ActiveRecord::Migration + def change + create_table :tag_hierarchies, :id => false do |t| + t.integer :ancestor_id, :null => false # ID of the parent/grandparent/great-grandparent/... tag + t.integer :descendant_id, :null => false # ID of the target tag + t.integer :generations, :null => false # Number of generations between the ancestor and the descendant. Parent/child = 1, for example. + end - # For "all progeny of..." selects: - add_index :tag_hierarchies, [:ancestor_id, :descendant_id], :unique => true + # For "all progeny of..." selects: + add_index :tag_hierarchies, [:ancestor_id, :descendant_id], :unique => true - # For "all ancestors of..." selects - add_index :tag_hierarchies, [:descendant_id] - end + # For "all ancestors of..." selects + add_index :tag_hierarchies, [:descendant_id] end - ``` + end + ``` 6. Run ```rake db:migrate``` 7. If you're migrating away from another system where your model already has a ```parent_id``` column, run ```Tag.rebuild!``` and the @@ -64,45 +65,45 @@ ### Creation Create a root node: - ```ruby - grandparent = Tag.create(:name => 'Grandparent') - ``` +```ruby +grandparent = Tag.create(:name => 'Grandparent') +``` Child nodes are created by appending to the children collection: - ```ruby - child = parent.children.create(:name => 'Child') - ``` +```ruby +child = parent.children.create(:name => 'Child') +``` You can also append to the children collection: - ```ruby - child = Tag.create(:name => 'Child') - parent.children << child - ``` +```ruby +child = Tag.create(:name => 'Child') +parent.children << child +``` Or call the "add_child" method: - ```ruby - parent = Tag.create(:name => 'Parent') - grandparent.add_child parent - ``` +```ruby +parent = Tag.create(:name => 'Parent') +grandparent.add_child parent +``` Then: - ```ruby - puts grandparent.self_and_descendants.collect{ |t| t.name }.join(" > ") - "grandparent > parent > child" +```ruby +puts grandparent.self_and_descendants.collect{ |t| t.name }.join(" > ") +"grandparent > parent > child" - child.ancestry_path - ["grandparent", "parent", "child"] - ``` +child.ancestry_path +["grandparent", "parent", "child"] +``` -### <code>find_or_create_by_path</code> +### find_or_create_by_path We can do all the node creation and add_child calls from the prior section with one method call: ```ruby child = Tag.find_or_create_by_path(["grandparent", "parent", "child"]) @@ -113,13 +114,13 @@ column is ```name```, which can be changed with the :name_column option provided to ```acts_as_tree```. Note that any other AR fields can be set with the second, optional ```attributes``` argument. - ```ruby - child = Tag.find_or_create_by_path(%w{home chuck Photos"}, {:tag_type => "File"}) - ``` +```ruby +child = Tag.find_or_create_by_path(%w{home chuck Photos"}, {:tag_type => "File"}) +``` This will pass the attribute hash of ```{:name => "home", :tag_type => "File"}``` to ```Tag.find_or_create_by_name``` if the root directory doesn't exist (and ```{:name => "chuck", :tag_type => "File"}``` if the second-level tag doesn't exist, and so on). ### Available options @@ -166,18 +167,18 @@ Polymorphic models are supported: 1. Create a db migration that adds a String ```type``` column to your model 2. Subclass the model class. You only need to add acts_as_tree to your base class. - ```ruby - class Tag < ActiveRecord::Base - acts_as_tree - end - class WhenTag < Tag ; end - class WhereTag < Tag ; end - class WhatTag < Tag ; end - ``` +```ruby +class Tag < ActiveRecord::Base + acts_as_tree +end +class WhenTag < Tag ; end +class WhereTag < Tag ; end +class WhatTag < Tag ; end +``` ## Change log ### 2.0.0 @@ -189,9 +190,13 @@ ### 3.0.0 * Support for polymorphic trees * ```find_by_path``` and ```find_or_create_by_path``` signatures changed to support constructor attributes * tested against Rails 3.1.3 + +### 3.0.1 + +* Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/mceachen/closure_tree/pull/5))! ## Thanks to * https://github.com/collectiveidea/awesome_nested_set * https://github.com/patshaughnessy/class_factory