README.md in closure_tree-3.0.2 vs README.md in closure_tree-3.0.3
- old
+ new
@@ -1,65 +1,68 @@
# Closure Tree
+[](http://travis-ci.org/mceachen/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,
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
+## Installation
-Note that closure_tree supports Rails 3. Rails 2, not so much.
+Note that closure_tree only supports Rails 3.0 and later, and has test coverage for MySQL, PostgreSQL, and SQLite.
1. Add this to your Gemfile: ```gem 'closure_tree'```
2. Run ```bundle install```
3. Add ```acts_as_tree``` to your hierarchical model(s) (see the <em>Available options</em> section below for details).
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
end
```
+ Note that if the column is null, the tag will be considered a root node.
+
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.
+ default the table name will be the model's table name, followed by
+ "_hierarchies". 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
- # For "all progeny of..." selects:
+ # For "all progeny of…" selects:
add_index :tag_hierarchies, [:ancestor_id, :descendant_id], :unique => true
- # For "all ancestors of..." selects
+ # 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
+7. If you're migrating from another system where your model already has a
```parent_id``` column, run ```Tag.rebuild!``` and the
- ..._hierarchy table will be truncated and rebuilt.
+ …_hierarchy table will be truncated and rebuilt.
If you're starting from scratch you don't need to call ```rebuild!```.
## Usage
@@ -152,11 +155,11 @@
* ```tag.leaf?``` returns true if this is a leaf node. It has no children.
* ```tag.leaves``` returns an array of all the nodes in self_and_descendants that are leaves.
* ```tag.level``` returns the level, or "generation", for this node in the tree. A root node == 0.
* ```tag.parent``` returns the node's immediate parent. Root nodes will return nil.
* ```tag.children``` returns an array of immediate children (just those nodes whose parent is the current node).
-* ```tag.ancestors``` returns an array of [ parent, grandparent, great grandparent, ... ]. Note that the size of this array will always equal ```tag.level```.
+* ```tag.ancestors``` returns an array of [ parent, grandparent, great grandparent, … ]. Note that the size of this array will always equal ```tag.level```.
* ```tag.self_and_ancestors``` returns an array of self, parent, grandparent, great grandparent, etc.
* ```tag.siblings``` returns an array of brothers and sisters (all at that level), excluding self.
* ```tag.self_and_siblings``` returns an array of brothers and sisters (all at that level), including self.
* ```tag.descendants``` returns an array of all children, childrens' children, etc., excluding self.
* ```tag.self_and_descendants``` returns an array of all children, childrens' children, etc., including self.
@@ -198,9 +201,15 @@
* Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, [jheiss](https://github.com/mceachen/closure_tree/pull/5))!
### 3.0.2
* Fix for ancestry-loop detection (performed by a validation, not through raising an exception in before_save)
+
+### 3.0.3
+
+* Added support for ActiveRecord's whitelist_attributes
+ (Make sure you read [the Rails Security Guide](http://guides.rubyonrails.org/security.html), and
+ enable ```config.active_record.whitelist_attributes``` in your ```config/application.rb``` ASAP!)
## Thanks to
* https://github.com/collectiveidea/awesome_nested_set
* https://github.com/patshaughnessy/class_factory