views:

69

answers:

1

Hi there, I hope this question hasn't been asked before:

I'm using the ancestry gem to manage my tree structure. I'm using a function which returns the descendants of a node to a certain number of levels. Here's a simplistic example of what it's returning:

[{:name => 'node 1', :depth => 1}, {:name => 'node 2', :depth => 2}
 {:name => 'node 3', :depth => 1}, {:name => 'node 4', :depth => 1}]

In reality those are records ordered correctly so that all the children, grandchildren etc... of a record appear after that record, so we can assume that 'node 2' is the child of 'node 1'. We can also prove this with the extra information that the method returns which I haven't included in this example to make it simpler.

I'm wanting to turn this into an unordered list in the most efficient manner possible:

<ul>
  <li>node 1
    <ul>
      <li>node 2</li>
    </ul>
  </li>
  <li>node 3</li>
  <li>node 4</li>
</ul>

And that's where I'm stuck. Having an ordered array of values like the above is great for avoiding the recursive code one normally needs to use to produce a nester unordered list. I'm thinking that perhaps simply mapping the members of the array and inserting the appropriate UL's and LI's would be the quickest way to go?

Looking forward to seeing your ideas!

Brendon

A: 

This ERB template should do the trick. Extract the code to a helper or a partial for tidiness.

<%
# lets assume that your array is an a variable
# called list
list = [ {:name => 'node 1', :depth => 1}, 
         {:name => 'node 2', :depth => 2},
         {:name => 'node 3', :depth => 1}, 
         {:name => 'node 4', :depth => 1}]

%>
<% depth = 1%>
<ul>
<%list.each do |cfg|%>
  <%if depth < cfg[:depth] %> 
    <ul>
  <%elsif depth > cfg[:depth] %>
      <%
      # take care of the free fall
      (depth - cfg[:depth]).times do
      %>
        </ul>   
      <%end%>
  <%end%>
  <li> <%= cfg[:name] %></li>
  <%depth = cfg[:depth] %>
<%end%>
<%
# take care of the final free fall 
depth.times do 
%>
  </ul>
<%end%>
KandadaBoggu
Looks good thank you :) Unfortunately the need for it has gone as I was assuming too much about the incoming data, it wasn't in the correct order as it didn't take into account the parentage information. Hopefully this is helpful to someone in the future though :)
Brendon Muir