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.