Ruby on Rails上的递归树

时间:2013-01-06 05:07:40

标签: ruby-on-rails recursion

以下是迭代树,在html.erb中完成,它只在树结构中达到两个级别:

      <ul>
    <li><%= root_template.id  %></li>
      <ul>
          <% for template in root_template.children  %>
              <li><%= template.id  %></li>
              <% if template.has_children? %>
                <ul>
                <% for template_child in template.children  %>
                    <li><%= template_child.id  %></li>
                <% end %>
                </ul>
              <% end %>
          <% end %>
      </ul>
  </ul>

结果: iterative

我想在帮助程序文件中移动代码并应用递归来达到所有级别:

html.erb(所以,从模板设置根目录):

  <% html = '' %>
  <ul>
    <li><%= root_template.id  %></li>
    <ul>
        <%= recursive_tree root_template, html %>
    </ul>
  </ul>

然后帮助方法:

  def recursive_tree(root, html)
    html << ''
    if !root.has_children?
      html << "<li>#{root.id}</li>"
      return html.html_safe
    else
      for template_child in root.children
        html << "<ul>#{recursive_tree(template_child, html)}</ul>"
      end
    end
    return html.html_safe
  end

结果:Wrong Recursive Result

我已经花了一天的时间来弄清楚如何从帮助程序向模板发送正确的html,现在无法弄清楚这种递归和解决方案的问题,即使我使用了调试器。有什么意见吗?

1 个答案:

答案 0 :(得分:1)

我可以在这里看到的一个问题是你需要使用html_safe。由于您将html_safe作为递归方法的一部分,因此会为更深层节点反复调用它。

您的实现中出现的另一个问题是<li>标记未正确包装<ul>标记,因此对于具有多个子节点的节点,这可能会得到错误的结果

也许你可以稍微改变一下递归方法(主要是伪代码):

def recursive_tree(root)
  res = ''
  if root
    res = "<li>#{root.id}"
    # if root has children
    #   add <ul>
    #   for each of the children res << recursive_tree(child)
    #   add </ul>
    # end
    res << "</li>"
  end
  res
end

现在添加一些包装函数来创建初始列表并添加html_safe:

wrapping_func(root)
  "<ul>#{recursive_tree(root)}</ul>".html_safe
end
顺便说一下,如果你向你的问题添加你期望的结构,以及html输出是什么,它可能会有所帮助。