$ show ClosureTree/closure_tree
ClosureTree is a mature Ruby gem that adds closure-table hierarchy support to ActiveRecord models via a `has_closure_tree` macro. It maintains a separate `_hierarchies` table storing ancestor/descendant pairs with generation depth, enabling O(1) SELECTs for ancestors, descendants, siblings, leaves, and roots. The gem handles the full lifecycle: node creation inserts a self-referencing row plus copies of the parent's ancestor rows (2 INSERTs), reparenting rebuilds the affected hierarchy, and destruction cleans up references with configurable dependent behavior (nullify, adopt, destroy, delete_all). It supports STI, UUID primary keys, deterministic numeric ordering with preorder traversal, scoped multi-tenant trees, PostgreSQL schema-qualified tables, and multi-database setups (PostgreSQL/MySQL/SQLite simultaneously). Concurrency safety is provided through the with_advisory_lock gem with customizable lock names and per-instance lock granularity for multi-tenant use cases. The architecture is notably clean: a `ClosureTree::Support` instance (`_ct`) encapsulates all implementation details to avoid polluting the host model's namespace, and focused mixins (Finders, HashTree, Digraphs, DeterministicOrdering, HierarchyMaintenance) are composed by the `has_closure_tree` entry point. The code demonstrates sophisticated cross-database SQL engineering — MySQL uses user variables for gap-free sibling reordering, PostgreSQL uses window functions, and Arel query builders handle adapter-specific quoting. The test suite is exceptional: it runs against Ruby 3.4/4.0, Rails 7.2 through edge, and all three database engines, with concurrency tests, query-count assertions, and shared example suites for both integer and UUID primary keys. The gem is actively maintained with release-please automation, semantic versioning, and a detailed changelog spanning over a decade of development.
The LLM identified 5 files worth highlighting for reuse:
A factory that selects a database-adapter-specific reordering strategy: MySQL uses session variables (`SET @i = 0` with an ordered UPDATE), PostgreSQL uses `row_number() OVER (ORDER BY ...)` with a `DISTINCT FROM` guard to skip no-op updates, and a generic fallback iterates in Ruby. This is a textbook example of optimizing one logical operation per RDBMS while keeping a uniform interface, and the module is self-contained enough to extract into any multi-database Rails project.
Implements `has_closure_tree_root`, which loads an entire tree plus arbitrary nested associations in a constant number of queries by fetching `self_and_descendants.includes(*assoc_map)` once, then manually wiring up parent/children association targets and inverse belongs_to associations in memory. The memoization keyed by association map and the `MultipleRootError` guard show careful edge-case handling. This is a genuinely reusable pattern for any ORM tree structure where N+1 traversal must be eliminated.
Builds the hierarchy INSERT (copy parent's ancestor rows with generations+1) and the double-wrapped DELETE subquery that works around MySQL's 'can't specify target table for UPDATE in FROM clause' limitation while remaining correct on PostgreSQL. The `to_sql_with_connection` method routes Arel ASTs through the active connection's visitor so quoting is adapter-correct. This encapsulates the hardest SQL in the gem into testable, reusable query-builder methods.
Builds a nested `ActiveSupport::OrderedHash` tree from a single SQL query by joining the hierarchy table grouped by descendant with `MAX(generations)` as depth, then assembling the hash in one pass over the result set using an id-to-hash lookup table. The `limit_depth` option is pushed into a HAVING clause so depth limiting happens in SQL, not Ruby. This is a clean, reusable pattern for converting flat relational rows into nested structures without recursion or N+1 queries.
The `Support` class is the architectural keystone: it holds all per-model configuration and helper logic behind a single `_ct` accessor so the host model only sees the public tree API. It validates options (scope types, advisory-lock/timeout conflicts), dynamically extends itself with the correct `NumericOrderSupport` adapter, computes hierarchy table names (including PostgreSQL schema-qualified names and table prefix/suffix handling), and centralizes advisory-lock acquisition with transaction-level lock support for PostgreSQL. This namespace-isolation pattern is worth studying for any Ruby gem that must inject substantial behavior into user models.