Add a tree to your rails application

I was looking for a tree structure for a tagging application and I decided to check out wether a solution different from acts_as_tree was available.

I stumbled upon Closure_tree and I was sold: it’s really fast and supports lots of customisations and features.

The installation is straightforward:

  1. add the gem (closure_tree)
  2. add a parent_id column to the model of yours you want to behave like a tree
  3. create a migration to generate a TagHierarchy table to store the tree structure.

For all the nitty-gritty details, check out the installation doc.

The basics commands to create a node and its relatives are what you expect from ActiveRecord relationships:

parent = Tag.create(:name => 'Parent')
and a child:

child = parent.children.create(:name => 'Child')

But what really interested me, was the ability to create a hierarchy quickly and with only one call:

child = Tag.find_or_create_by_path(["grandparent", "parent", "child"])

Every tag of the chain will be created only if not already present.

And as a bonus, it supports Graphviz for rendering the trees.

The only feature it doesn’t have, is the support for multiple parents: it’d have been interesting to have it, but the author says pull requests are welcomed, so if the need arises, I may contribute to it. 😉

ps.

As for the speed, I didn’t need huge performances for my pet project, so it wasn’t a requirement, but it’s nice to know that it requires only one SELECT to get almost all the informations:

  • Fetch your whole ancestor lineage in 1 SELECT.
  • Grab all your descendants in 1 SELECT.
  • Get all your siblings in 1 SELECT.
  • Find a node by ancestry path in 1 SELECT.

Leave a Reply

wpDiscuz