Finding our current depth in a tree (acts_as_tree)

Hi there, I’m building an indexbar that has two parameters:

  • It’ll display the current item, its siblings and it’s parents
    siblings (recursively) to a height provided in variable.
  • It’ll stop climbing if we reach a certain depth as defined by
    another variable.

An example:

*  Home
* Products
      o Products Home
      o Product Category 1
      o Product Category 2
            + Category Home
            + Product 1
            + Product 2
                  # Overview
                  # Specifications
                  # Enquire
            + Product 3
            + Product 4
      o Product Category 3
      o Product Category 4
* Applications
* Services
* Links
* About Us
* Contact Us

The current page is Overview and the rest is built around it.

The problem I’m facing is that I’d like to top it from ever climbing
higher than level 2 (That is the level that has the product
categories), so the indexbar would look like:

      o Products Home
      o Product Category 1
      o Product Category 2
            + Category Home
            + Product 1
            + Product 2
                  # Overview
                  # Specifications
                  # Enquire
            + Product 3
            + Product 4
      o Product Category 3

I would like to be able to provide a variable (the number 2 in this
case) and have my code stop when it detects that the current tree
depth is equal to two.

I can think of many hacky ways to do this, but I’d like this check to
be as inexpensive as possible. Does anyone have any suggestions?

Here’s the code:

def index_bar_range(tree, component_instance_id, bar_parameters,
rett=nil)
# This indexbar will behave as follows:
# It starts at the level of the current component instance and
shows its siblings
# It then shows its parents siblings surrounging it and its
siblings (recursively)
# It will stop when it gets to the max depth or when it gets to
the level of the site
# that is defined as the top level to display - or it hits home
first.

return unless bar_parameters.length == 2
component_instance =

ComponentInstance.find_current_by_id(component_instance_id)
@depth ||= bar_parameters[1].to_i
ret = “\n


    tree.each do |node|
    if node.parent_id && node.parent_id ==
    component_instance.parent_id && availability_checks(node)
    ret += “\n\t<li” + if @component_instance && node.id ==
    @component_instance.id then " class=“uber”" else ‘’ end + “>”
    ret += link_to h(node.name), {:action => ‘show’, :controller
    => ‘/’ + node.component.technical_name, :id => node.instance.id }
    ret += rett if rett && node.id == component_instance.id
    ret += “\n”
    end
    end
    ret += “
\n”
@depth -= 1
# Go upward and put all those parents in
if component_instance.parent_id && @depth != 0 ############ This
is where I’d put the check for the level
index_bar_range(tree, component_instance.parent_id,
bar_parameters, ret)
else
@depth = nil
return ret
end
end

def availability_checks(node)
node.isEnabledRecursive? && node.viewable?(user) &&
node.parent.authenticated?(session, user) && !
node.component.backend_only && !(node.instance.respond_to?(‘private’)
&& node.instance.private)
end

def sitetree
@sitetree ||= ComponentInstance.find_current(:all, :order =>
‘position’)
end

This is all in a helper and we just call it from a view providing the
parameters and the currently viewed item.id. I’m using acts_as_tree.

Cheers,

Brendon

Here’s a paste of the code above:

http://pastie.org/223022