ruby-on-railsruby-on-rails-4ancestry

How do I easily retrieve the total depth of a tree in ancestry?


Ancestry has many wonderful scopes and methods, including node.depth (which returns a depth level - i.e. 0 for root nodes, 1 for the child, etc.).

It also has some scopes that allow you to traverse a tree by depth, e.g. node.subtree(:to_depth => 2).

But I don't see anything that indicates how to calculate/retrieve the total depth of the entire tree - from the root to the last node.

The only thing I can think of is to create a total_depth_cache column on my model, that as a new child is added, it increments that. But then I have to write the logic to manage that (i.e. whenever all children are deleted, it decrements - if there is just 1 level, but if a child with say 3 levels of children gets deleted, the depth would then have to be updated accordingly). That can get pretty complicated very quickly.

Is there a simpler way to do this?


Solution

  • here's a last_depth recursive method you can add to the model...

    class Node
      def last_depth
        if child_ids.empty?
          return depth
        else
          return children.map{|c| c.last_depth}.max
        end
      end
    end
    

    EDIT: to clarify, the method will return the current depth of a node if it has no children, otherwise it will call itself on all the children of the current node and return the largest result. The net result will be the largest "depth" value in the tree.