Я не уверен, что это лучшая практика, но я использовал похожий код для рендеринга дерева проекта.
Более быстрой альтернативой является создание вспомогательного метода, выполняющего ту же работу (рекурсивный обход дерева и добавление частичных строк в строку результата). Это немного стиль PHP :( но для такого небольшого количества HTML это нормально, я думаю :)
Помощник выглядит так:
def render_node(node)
res = "<ul>"
...
node.items.each {|n| res << render_node(n)}
...
res << "</ul>"
res
end
Тогда это используется так:
<%=render_node ProjectTree.new%>