Recursive Rails partials

Love it when I make the world slightly better by improving an Open Source product I use.

I am a big fan of Ancestry, software that helps define relationships between things. Often used to organize categories.

It provides a means to spit out all the items it contains, neatly arranged. But! The list can be arbitrarily deep. Seven, 42, a hundred…. this freedom is somewhat of a nuisance when you’re trying to automate things.

To solve it, you need code that runs itself any amount of time.

Recursion. Tum dum duuummm!!

via GIPHY

Rails partials

The Ancestry wiki contains code examples that build an HTML list. I don’t think it’s great code, because it doesn’t use the power of Rails very much. When rendering things, of course you should use a partial.

But how to recursively render a partial?

Well, a helper for starters:

module AncestryHelper
  # Recursively render a partial from an Ancestry arranged subtree.
  def arranged_tree_table_rows(tree)
    tree.each do |node, children|
      concat render partial: 'tree_node', object: node
      arranged_tree_table_rows(children) if children.present?
    end
  end
end

The subtree goes in the controller:

class SomeController < ApplicationController
  def index
    @subtree = TreeNode.find_by_name('Crunchy').subtree.arrange
  end
end

And the view takes all credit:

<% arranged_tree_table_rows(@subtree) %>

VoilĂ . Add caching and enjoy!