Rails helper方法:嵌套哈希到嵌套HTML列表

我正在尝试编写一个Rails帮助器方法来将嵌套的哈希转换为嵌套的HTML列表。

例如:

{ :parent => "foo", :children => [ { :parent => "bar", :children => [ { :parent => "baz", :children => [] } ] } ] } 

应成为:

 
  • foo
    • bar
      • baz

散列可以具有任意数量的级别,以及每个级别的任意数量的父级。

请达到这个目的的最佳方法是什么?

您可以使用递归方法呈现以散列到嵌套的列表集。 将此放在您的相关帮助者中:

 def hash_list_tag(hash) html = content_tag(:ul) { ul_contents = "" ul_contents << content_tag(:li, hash[:parent]) hash[:children].each do |child| ul_contents << hash_list_tag(child) end ul_contents.html_safe }.html_safe end 

Zach Kemp的回答非常有效地解决了这个问题。 如果你正在寻找一些更通用的东西(一个你不会知道密钥名称的嵌套哈希),就像我一样,以下模块可能会有所帮助(同样在https://github.com/sjohnson/auto_hash_display上更多细节):

 module HashFormatHelper # These methods add classes to the HTML structure that are defined in Bootstrap (and can be defined for other CSS frameworks) def format_hash(hash, html = '') hash.each do |key, value| next if value.blank? if value.is_a?(String) || value.is_a?(Numeric) html += content_tag(:ul, class: 'list-group') { ul_contents = '' ul_contents << content_tag(:li, content_tag(:h3, key.to_s.underscore.humanize.titleize), class: 'list-group-item') ul_contents << content_tag(:li, value, class: 'list-group-item') ul_contents.html_safe } elsif value.is_a?(Hash) html += content_tag(:ul, class: 'list-group') { ul_contents = '' ul_contents << content_tag(:li, content_tag(:h3, key.to_s.underscore.humanize.titleize), class: 'list-group-item') inner = content_tag(:li, format_hash(value), class: 'list-group-item') ul_contents << inner ul_contents.html_safe } elsif value.is_a?(Array) html += format_array(value) else Rails.logger.info "Unexpected value in format_hash: #{value.inspect}" Rails.logger.info "value type: #{value.class.name}" end end html.html_safe end def format_array(array, html = '') array.each do |value| if value.is_a?(String) html += content_tag(:div, value).html_safe elsif value.is_a?(Hash) html += format_hash(value) elsif value.is_a?(Array) html += format_array(value) else Rails.logger.info "Unexpected value in format_array: #{value.inspect}" Rails.logger.info "value type: #{value.class.name}" end end html end end 

此代码还可用于通过将哈希值设置为等于Hash.from_xml(your_xml_data)然后将其传递给format_hash(哈希)来显示XML。

请注意,from_xml方法可能会剥离XML标记属性,因此最适合没有属性的XML。