9.6.1 (2026-03-07)
- triggger release (f334952)
9.6.0 (2026-02-16)
- raise error when advisory lock cannot be acquired within configured timeout (#480) (c030385)
- sibling reordering when node changes parent or scope (#484) (254ba36)
9.5.0 (2026-01-21)
- Add
dependent: :adoptoption forhas_closure_tree(#471) (d47d7c9) - add PostgreSQL schema-qualified table name support (#462) (5f9006c)
- Add runtime advisory lock name customization and multi-database documentation (#454) (d6ffd73)
- migrate from ActiveSupport::Autoload to Zeitwerk (#457) (d18e80c)
- rewrite with clean api (#451) (f56f2e1)
- use with_advisory_lock that support rails 8.2 (#479) (bca6231)
- add implicit_order_column for Rails 8.1+ compatibility (#464) (f384303)
- configure release-please to recognize v8.0.0 release (#455) (fc34f21)
- eager loading of hierarchies by defining the primary key (#465) (8c7e490)
- hierarchy class inheritance to avoid STI validations (#392) (#472) (73b07a6)
- improve api usage (#475) (cde4d29)
- nil scope values being excluded from scope filtering (#476) (f45880e)
- restore proper deprecation for database_less configuration (#459) (de8b402)
9.3.0 (2025-11-19)
9.2.0 (2025-10-17)
9.1.1 (2025-07-24)
9.1.0 (2025-07-23)
9.0.0 (2025-07-21)
- Add runtime advisory lock name customization and multi-database documentation (#454) (d6ffd73)
- rewrite with clean api (#451) (f56f2e1)
- Drop support to EOL ruby and rails
- Reference ancestor_hierarchies in depth instead of ancestors to avoid n+1
- fix: hierarchy model with namespace should inherit from the superclass of basic model #384 (shawndodo)
- Add with_descendant to readme #381 (mattvague)
- Ruby 3.0 support
- Ruby 2.7 support
- Ordering raw SQL argument wrapped with Arel.sql
Closure Tree is now tested against Rails 6.0
- Directly require core_ext for String#strip_heredocPR 350
- Call Module#module_parent instead of deprecated #parentPR 354
Closure Tree is now tested against Rails 5.2
- Postpone configuration (database introspection)PR 264
- Fix "tree.find_by_path([])" PR 288
- Fixed generator specs and added migration version PR 292
- Eliminate deprecation warnings in ActiveRecord 5.2 PR 296
- When using 'oracle_enhanced', remove 'AS' on the table_name alias. PR 298
- README update PR 301
- Add
with_descendantfinder PR 302 - Fix pg version for rails prior 5.1 PR 303
- Test on Rails 5.2 & fix mysql for older Rails PR 304
- Test with ActiveRecord 5.2.0 PR 307
- README update PR 310
- FactoryBot linter failing for a model that uses closure_tree PR 311
- Added dont_order_roots option PR 312
- Added instance methods to determine the relationship between 2 nodes PR 314
- Add an instance method to check the relationship between 2 nodes: #family_of? PR 319
- Remove options restrictions on has_closure_tree_root PR 321
- Fix uninitialized variable warnings PR 323
Closure Tree is now tested against Rails 5.1, and just passed 50 contributors and 1000 stars on github! 🎉!
Note that Closure Tree has moved to a new "Closure Tree" github organization. Future gem releases will be done by other contributors.
- ActiveSupport 5.1 deprecation warnings were addressed in PR 262. Thanks, Charles Pence!
- ActiveSupport 5.1 test failures were fixed in PR 280. Thanks, Bobby Uhlenbrock!
- A database connection was leaked at startup, fixed in PR 263. Thanks, Andrey Novikov!
- Merged PR 258 which improves hierarchy maintenance with large trees. Thanks, Nikolay Bekirov!
- Merged PR 236 which adds documentation for
has_closure_tree_root. - Added ruby 2.4 and dropped Rails 4.1 from the build matrix.
prepend_childhandles invalid children properly now. Thanks Amit Saxena!- Dropped official support for jruby and ruby 2.0 (no code was changed)
- Fix for MySQL lock lengths. Thanks to Liam!
- Tom Smyth added eager tree loading
- Merged PR 200 which may or may not add support to SQLServer 2008 (but this is not a supported RDBMS).
- Added official support for ActiveRecord 5.0! Thanks to Abdelkader Boudih, Jay Fredlund, Veselin Stoyanov, and Aaron Russell for all the PRs.
- Add
database_lessconfiguration to not raise an error during build step when database is unavailable which is a common case in some PaaS like (Heroku, Catalyze, ..., etc).
- Andrew Kumanyaev dramatically improved mutation performance on large trees. Thanks for the PR!
- Martin Schmidt discovered and fixed build problems due to new versions of mysql2 and ammeter which broke Travis builds. Thanks for the PR!
- Fabien MICHEL updated the README with another example. Thanks for the PR!
- Dropped support for versions of Rails 3.2 and 4.0 (which are no longer supported).
- Dropped support for Ruby 1.9 and JRuby 1.9 (which are no longer supported).
- Added support for
.hash_treefrom.parentand.children. Addresses PR146. Thanks for reporting this and the breaking test, Mike!
- Eduardo Turiño renamed
acts_as_treetohas_closure_tree. We'll keep both annotations around for the forseeable future, but I think not name-colliding by default is strictly better. (Thanks for both the suggestion and PR!) - Ryan Selk made several enhancements to the migration generation (thanks!).
- ruok5 updated the README to clarify a heirarchy maintenance usecase. Thanks!
- Made migrations error with a helpful message if the target didn't have the
has_closure_treeoracts_as_treeannotation. This addresses issue 131.
- Fixed bug in
rails g closure_tree:migration(introduced by me, not by seuros!) that was reported and fixed by Rich Kuo. Thanks!
- Abdelkader Boudih added a database generator for the hierarchies table. Thanks!
- Jason Weathered fixed issue #117
with the preordered traversal code that assumed the primary key column was called
id. Thanks!
find_by_pathandfind_or_create_by_pathnow takes either an array of strings or an array of attribute hashes, which can include the inheritance column for STI support.- Removed the extraneous
base_classacts_as_treeoption—it needlessly duplicated ActiveRecord's method. - Removed the unused
nameacts_as_treeoption.
- Cleaned up the inheritance support methods to delegate correctly to ActiveRecord
- Fixed a query generation error when ancestor paths exceeded 50 items.
- Documented the
.touchoption
- More goodness from Abdelkader Boudih, including rspec 3 support.
- Pulled in 106 which fixed a bug introduced in 4.6.0 which broke if the numeric ordering column wasn't named 'sort_order'. Tests have been added. Thanks for the fix, Fission Xuiptz!
- Address issue 60 (use
.empty?rather than.nil?—thanks for the suggestion, Leonel Galán, Doug Mayer and Samnang Chhun!
-
Deterministically ordered trees are guaranteed to have a sort_order now.
This may be a breaking change if you're expecting sort_order to be nullable.
Many thanks to David Schmidt for raising and working on the issue!
-
Added
append_childandprepend_child -
All raw SQL is now
strip_heredoc'ed
- Merged a bunch of great changes from Abdelkader Boudih, including a change to use appraisal
- Added Travis builds for Rails 4.1.1 and Ruby 2.1.2
- Dropped support for Rails 3.1, as it is no longer receiving security patches. See http://rubyonrails.org/security/ for more information.
-
Added
.self_and_descendant_idsand.self_and_ancestors_idsfrom PR92. Thanks, Kir Shatrov! -
Dropped support for Rails 3.0.
-
Use foreigner to prove that things are inserted and deleted without violating foreign key constraints
-
Added Rails 4.1.0.rc2 as a Travis CI build target
- Support for Heroku's cray assets:precompile hack for Rails 4. Addresses issue 78. Thanks for the assist, Alex Bowman.
- More massaging for Rails 4 and
attr_accessiblesupport
self_and_ancestorsandancestry_hierarchyare reloaded when nodes are reparented. Addresses issue 68. Thanks for the assist, Ivan Stana.
- Explicitly added MIT licensing to the gemspec.
-
Fix for potential deadlock from
delete_hierarchy_referencesnot being called within an advisory lock. Thanks, Armando Guereca, for finding that! -
Sped up find_or_create_by_path to skip cycle detection validation. A node whose ancestry was 200-deep took 20 seconds to create (!!), and now takes < 1 second.
-
Fixed issue with MySQL that prevented nodes > 60 levels deep from being created
- Support for
root?,child?, and proper parent-child associations when both the parent and the child are not persisted. Addresses issue 64. Thanks for the help, Gabriel Mazetto!
- Fixed
attr_accessible?error introduced in 4.2.2 (issue 66). - Switched to use new WithAdvisoryLock::DatabaseAdapterSupport (in v0.0.9) to add Postgis support
- Support attr_accessible and strong_attributes even if you're on Rails 4
- Deleting from NumericDeterministicOrdering doesn't create sort order gaps anymore.
- Added
with_ancestor(*ancestors). Thanks for the idea, Matt! - Applied Leonel Galan's fix for Strong Attribute support
find_or_create_bynow uses passed-in attributes as both selection and creation criteria. Thanks for the help, Judd Blair! Please note that this changes prior behavior—test your code with this new version!ct_advisory_lockwas moved into the_ctsupport class, to reduce model method pollution- Moved a bunch of code into more focused piles of module mixins
- Added support for Rails 4.0.0.rc1 and Ruby 2.0.0 (while maintaining backward compatibility with Rails 3, BOOYA)
- Added
#to_dot_digraph, suitable for Graphviz rendering
-
Numeric, deterministically ordered siblings will always be [0..#{self_and_siblings.count}] (previously, the sort order might use negative values, which broke the preordering). Resolves issue 49. Thanks for the help, Leonel Galan, Juan Hoyos, and Michael Elfassy!
-
The
orderoption can be a symbol now. Resolves issue 46.
-
Moved all of closure_tree's implementation-detail methods into a
ClosureTree::Supportinstance, which removes almost all of the namespace pollution in your models that wasn't for normal consumption. If you were using any of these methods, they're now available through the "_ct" class and instance member.This change may break consumers, so I incremented the major version number, even though no new functionality was released.
-
Prevent faulty SQL statement when
#siblingsis called on an unsaved records. Resolves issue 52. Perfect pull request by Gary Greyling. -
The
.rootsclass method now correctly respects the:orderoption. Resolves issue 53. Thanks for finding this, Brendon Muir!
-
Multipart constant names like "Admin::PageHierarchy" are now supported. Resolves issue 47. Thanks for the perfect pull request, Simon Menke!
-
Committing transactions involving large numbers of hierarchy model classes was very slow due to hash collisions in the hierarchy class. A better hash implementation addressed issue 48. Thanks, Joel Turkel!
- Added
#roots_and_descendants_preordered. Thanks for the suggestion, Leonel Galan!
- Added
.child_ids. - Removed
dependent => destroyon the descendant_hierarchy and ancestor_hierarchy collections (they were a mistake). - Clarified documentation for creation and child associations.
Because
Tag.create!(:parent => ...)requires a.reload, I removed it as an example.
All three of these improvements were suggested by Andrew Bromwich. Thanks!
- find_by_path uses 1 SELECT now. BOOM.
- Double-check locking for find_or_create_by_path
- Support for preordered descendants. This requires a numeric sort order column. Resolves feature request 38.
- Moved modules from
acts_as_treeinto separate files
Due to MySQL's inability to lock rows properly, I've switched to advisory_locks for all write paths. This will prevent deadlocks, addressing issue 41.
- Moved requires into ActiveSupport.on_load
- Added
require 'with_advisory_lock'
Thread safety!
- Advisory locks were
integrated with the class-level
find_or_create_by_pathandrebuild!. - Pessimistic locking is used by the instance-level
find_or_create_by_path.
- Don Morrison massaged the #hash_tree query to
be more efficient, and found a bug in
hash_tree's query that resulted in duplicate rows, wasting time on the ruby side.
- Added workaround for ActiveRecord::Observer usage pre-db-creation. Addresses issue 32. Thanks, Don Morrison!
- Added support for Rails 4's strong parameter. Thanks, James Miller!
- Use
quote_table_nameinstead ofquote_column_name. Addresses issue 29. Thanks, Marcello Barnaba!
- Use
.pluckwhen available for.ids_from. Addresses issue 26. Thanks, Chris Sturgill!
- Fixed issue 24, which optimized
#hash_treefor roots. Thanks, Saverio Trioni!
- Fixed issue 23, which added support for
#siblingswhen sort_order wasn't specified. Thanks, Gary Greyling!
- Fixed issue 20, which affected deterministic ordering when siblings where different STI classes. Thanks, edwinramirez!
Added support for:
:hierarchy_class_nameas an option- ActiveRecord::Base.table_name_prefix
- ActiveRecord::Base.table_name_suffix
This addresses issue 21. Thanks, Judd Blair!
- Added
find_all_by_generationfor feature request 17.
- Fixed issue 18, which affected append_node/prepend_node ordering when the first node didn't have an explicit order_by value
- Reverted .gemspec mistake that changed add_development_dependency to add_runtime_dependency
Fixed issue 15:
- "parent" is now attr_accessible, which adds support for constructor-provided parents.
- updated readme accordingly
- Merged calebphillips' patch for a more efficient leaves query
- Added support for partially-unsaved hierarchies issue 13:
a = Tag.new(name: "a")
b = Tag.new(name: "b")
a.children << b
a.save
- Added
hash_tree.
- Added
ancestor_ids,descendant_ids, andsibling_ids - Added example spec to solve issue 9
- Added support for deterministic ordering of nodes.
- Switched to using
has_many :thoughrather thanhas_and_belongs_to_many
- Merged pull request to fix
.siblingsand.self_and_siblings(Thanks, eljojo!)
- Added support for ActiveRecord's whitelist_attributes
(Make sure you read the Rails Security Guide, and
enable
config.active_record.whitelist_attributesin yourconfig/application.rbASAP!)
- Fix for ancestry-loop detection (performed by a validation, not through raising an exception in before_save)
- Support 3.2.0's fickle deprecation of InstanceMethods (Thanks, jheiss)!
- Support for polymorphic trees
find_by_pathandfind_or_create_by_pathsignatures changed to support constructor attributes- tested against Rails 3.1.3
- Had to increment the major version, as rebuild! will need to be called by prior consumers to support the new
leavesclass and instance methods. - Tag deletion is supported now along with
:dependent => :destroyand:dependent => :delete_all - Switched from default rails plugin directory structure to rspec
- Support for running specs under different database engines:
export DB ; for DB in sqlite3 mysql postgresql ; do rake ; done