Question

Pardon my ignorance, I'm new to Ruby, but not programming. I'm using a gem called Ancestry to store hierarchical data in my application. They have a method called "descendants" that returns a nested hash of all the descending children, grandchildren, etc.. in a node, but I'm having a hard time trying to loop through each node and output all the child nodes.

Here's what the data structure looks like

{
  #<Forum id: 16, name: "Parent 1", ancestry: "7", display_order: 1> =>{}, 
  #<Forum id: 17, name: "Parent 2", ancestry: "7", display_order: 2> =>{}, 
  #<Forum id: 13, name: "Parent 3", ancestry: "7", display_order: 3> =>
  {
    #<Forum id: 14, name: "Child 1", ancestry: "7/13", display_order: 1> =>{}, 
    #<Forum id: 15, name: "Child 2", ancestry: "7/13", display_order: 2> =>
    {
      #<Forum id: 18, name: "Grand Child", ancestry: "7/13/15", display_order: 1> =>{}, 
    }
  }
}

When I loop through that data using the code below, the parent nodes are the only ones that end up being rendered to the screen.

<% forum.descendants.arrange(:order => :display_order).map do |forum,key| %>
  <%= render :partial => 'forum', :locals => {:forum => forum} %>
<% end %>

How can I render the child nodes as well? I know they're accessible through the "key" variable, but I don't know how to tell when the "key" variable has data that I can render and how to output that data. Any suggestions?

Was it helpful?

Solution

You can check if the key is a hash by doing key.is_a?(Hash).

In your example, it will always evaluate to true because {} is an empty hash. You can check whether the hash is empty with key.empty?

To iterate through the nested hash, you can do it recursively something like this

def display hash
    hash.each do |key, val|
        # print key etc
        if val.is_a?(Hash)
            display val
        else
            # print value or whatever operation you want
        end
    end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top