README.md in closure_tree-6.0.0 vs README.md in closure_tree-6.1.0
- old
+ new
@@ -1,10 +1,10 @@
# Closure Tree
### Closure_tree lets your ActiveRecord models act as nodes in a [tree data structure](http://en.wikipedia.org/wiki/Tree_%28data_structure%29)
-Common applications include modeling hierarchical data, like tags, page graphs in CMSes,
+Common applications include modeling hierarchical data, like tags, threaded comments, page graphs in CMSes,
and tracking user referrals.
[![Build Status](https://secure.travis-ci.org/mceachen/closure_tree.png?branch=master)](http://travis-ci.org/mceachen/closure_tree)
[![Gem Version](https://badge.fury.io/rb/closure_tree.png)](http://rubygems.org/gems/closure_tree)
[![Code Climate](https://codeclimate.com/github/mceachen/closure_tree.png)](https://codeclimate.com/github/mceachen/closure_tree)
@@ -24,12 +24,12 @@
* [Find a node by ancestry path](#find_or_create_by_path) in 1 SELECT.
* __Best-in-class mutation performance__:
* 2 SQL INSERTs on node creation
* 3 SQL INSERT/UPDATEs on node reparenting
* __Support for [concurrency](#concurrency)__ (using [with_advisory_lock](https://github.com/mceachen/with_advisory_lock))
-* __Support for ActiveRecord 4.1, 4.2 and 5.0.alpha__
-* __Support for Ruby 2.2 and JRuby 9000__
+* __Support for ActiveRecord 4.1, 4.2 and 5.0__
+* __Support for Ruby 2.0, 2.1, 2.2, 2.3.1 and JRuby 9000__
* Support for reparenting children (and all their descendants)
* Support for [single-table inheritance (STI)](#sti) within the hierarchy
* ```find_or_create_by_path``` for [building out heterogeneous hierarchies quickly and conveniently](#find_or_create_by_path)
* Support for [deterministic ordering](#deterministic-ordering)
* Support for [preordered](http://en.wikipedia.org/wiki/Tree_traversal#Pre-order) traversal of descendants
@@ -107,10 +107,13 @@
`parent_id` column, run `Tag.rebuild!` and your
`tag_hierarchies` table will be truncated and rebuilt.
If you're starting from scratch you don't need to call `rebuild!`.
+NOTE: Run `rails g closure_tree:config` to create an initializer with extra
+ configurations. (Optional)
+
## Warning
As stated above, using multiple hierarchy gems (like `ancestry` or `nested set`) on the same model
will most likely result in pain, suffering, hair loss, tooth decay, heel-related ailments, and gingivitis.
Assume things will break.
@@ -143,15 +146,21 @@
```ruby
child3 = Tag.new(name: 'Third Child')
parent.add_child child3
```
+Or by setting the parent on the child :
+
+```ruby
+Tag.create(name: 'Fourth Child', parent: parent)
+```
+
Then:
```ruby
grandparent.self_and_descendants.collect(&:name)
-=> ["Grandparent", "Parent", "First Child", "Second Child", "Third Child"]
+=> ["Grandparent", "Parent", "First Child", "Second Child", "Third Child", "Fourth Child"]
child1.ancestry_path
=> ["Grandparent", "Parent", "First Child"]
```
@@ -273,10 +282,11 @@
* ```:hierarchy_table_name``` to override the hierarchy table name. This defaults to the singular name of the model + "_hierarchies", like ```tag_hierarchies```.
* ```:dependent``` determines what happens when a node is destroyed. Defaults to ```nullify```.
* ```:nullify``` will simply set the parent column to null. Each child node will be considered a "root" node. This is the default.
* ```:delete_all``` will delete all descendant nodes (which circumvents the destroy hooks)
* ```:destroy``` will destroy all descendant nodes (which runs the destroy hooks on each child node)
+ * ```nil``` does nothing with descendant nodes
* ```:name_column``` used by #```find_or_create_by_path```, #```find_by_path```, and ```ancestry_path``` instance methods. This is primarily useful if the model only has one required field (like a "tag").
* ```:order``` used to set up [deterministic ordering](#deterministic-ordering)
* ```:touch``` delegates to the `belongs_to` annotation for the parent, so `touch`ing cascades to all children (the performance of this for deep trees isn't currently optimal).
## Accessing Data
@@ -392,16 +402,16 @@
Note that all of ```node1```'s children's sort_orders will be incremented
* ```node1.prepend_sibling(node2)``` which will
1. set ```node2``` to the same parent as ```node1```,
2. set ```node2```'s order column to 1 less than ```node1```'s value, and
- 3. decrement the order_column of all children of node1's parents whose order_column is <>>= node2's new value by 1.
+ 3. increment the order_column of all children of node1's parents whose order_column is > node2's new value by 1.
* ```node1.append_sibling(node2)``` which will
1. set ```node2``` to the same parent as ```node1```,
2. set ```node2```'s order column to 1 more than ```node1```'s value, and
- 3. increment the order_column of all children of node1's parents whose order_column is >= node2's new value by 1.
+ 3. increment the order_column of all children of node1's parents whose order_column is > node2's new value by 1.
```ruby
root = OrderedTag.create(name: 'root')
a = root.append_child(Label.new(name: 'a'))
@@ -501,10 +511,26 @@
after do
FileUtils.remove_entry_secure ENV['FLOCK_DIR']
end
```
+### `bundle install` says `Gem::Ext::BuildError: ERROR: Failed to build gem native extension`
+
+When building from source, the `mysql2`, `pg`, and `sqlite` gems need their native client libraries
+installed on your system. Note that this error isn't specific to ClosureTree.
+
+On Ubuntu/Debian systems, run:
+
+```
+sudo apt-get install libpq-dev libsqlite3-dev libmysqlclient-dev
+bundle install
+```
+
+### Object destroy fails with MySQL 5.7+
+
+A bug was introduced in MySQL's query optimizer. [See the workaround here](https://github.com/mceachen/closure_tree/issues/206).
+
## Testing with Closure Tree
Closure tree comes with some RSpec2/3 matchers which you may use for your tests:
```ruby
@@ -536,24 +562,23 @@
## Testing
Closure tree is [tested under every valid combination](http://travis-ci.org/#!/mceachen/closure_tree) of
-* Ruby 2.2 (and sometimes head)
-* jRuby 9000 (and sometimes head)
-* The latest ActiveRecord 4.1, 4.2, and master branch
-* Concurrency tests for MySQL and PostgreSQL. SQLite is tested in a single-threaded environment.
+* Ruby 2.0, 2.2, 2.3.1
+* ActiveRecord 4.1, 4.2, and 5.0
+* PostgreSQL, MySQL, and SQLite. Concurrency tests are only run with MySQL and PostgreSQL.
Assuming you're using [rbenv](https://github.com/sstephenson/rbenv), you can use ```tests.sh``` to
run the test matrix locally.
## Change log
See the [change log](https://github.com/mceachen/closure_tree/blob/master/CHANGELOG.md).
## Thanks to
-* The more than 30 engineers around the world that have contributed their time and code to this gem
+* The 45+ engineers around the world that have contributed their time and code to this gem
(see the [changelog](https://github.com/mceachen/closure_tree/blob/master/CHANGELOG.md)!)
* https://github.com/collectiveidea/awesome_nested_set
* https://github.com/patshaughnessy/class_factory
* JetBrains, which provides an [open-source license](http://www.jetbrains.com/ruby/buy/buy.jsp#openSource) to
[RubyMine](http://www.jetbrains.com/ruby/features/) for the development of this project.