2009-08-25 5 views
0

J'utilise awesome_nested_set pour ma structure de site Web central. Je veux être capable de construire une barre d'index basée sur UL/LI hors de l'ensemble imbriqué, mais je veux aussi qu'elle profite de la faible intensité de base de données de l'ensemble imbriqué. Quand j'utilisais acts_as_tree, j'avais une fonction récursive qui construisait la barre d'index. Il s'est juste appelé s'il rencontrait des enfants etc ... Je me demande s'il y a une meilleure façon de le faire avec nested_set. Je suis venu avec ce qui suit à ce jour (non testé):Création récursive d'une barre d'index (basée sur UL, LI)

def recursive_indexbar(parent, parameters) 
    return unless parameters.length == 1 && parameters.first.to_i > 0 

    maximum_level = parent.level + parameters.first 

    content_tag :ul do 
     parent.descendants.current.visible.front_end.recurse do |component_instance, block| 
     content_tag :li, :class => (@item.component_instance == component_instance) ? 'uber' : false do 
      component_instance.name 
      unless component_instance.leaf? 
      content_tag :ul, block.call 
      end 
     end 
     end 
    end 
    end 

Maintenant, il ne fonctionne pas vraiment parce qu'il n'y a pas de fonction de récursion dans nested_set, je viens de prendre cette place de ce lien: http://dev.rubyonrails.org/ticket/9678. Voir le dernier commentaire sur la page.

Il y aura aussi des facilités pour aller seulement à de nombreux niveaux, mais cela est facile à implémenter.

Quelqu'un peut-il me donner des pointeurs?

Répondre

1

Donc, je vais y répondre alors :) Fondamentalement, j'ai utilisé un lambda et la fonction de retour pour aider à créer un tas de tableaux imbriqués avec du contenu. La vue décompile alors ce texte en droit:

def new_recursive(parent, parameters) 
    return unless parameters.length == 1 && parameters.first.to_i > 0 

    maximum_level = parent.level + parameters.first 

    recurse = lambda do |component_instance| 
     component_instance.children.current.visible.front_end.collect do |child| 
     content_tag :li, :class => (@item.component_instance == child ? 'uber' : nil) do 
      returning [] do |content| 
      content << link_to(child.name, [child.parent, child.instance]) 
      unless child.leaf? || child.level == maximum_level 
       content << content_tag(:ul, recurse.call(child)) 
      end 
      end 
     end 
     end 
    end 

    content_tag :ul, recurse.call(parent) 
    end 

Notez aussi l'utilisation de collect plutôt que chaque (qui semble plus logique). Collecter renvoie un tableau qui correspond à ce que nous voulons. Si vous arrêtez d'ajouter ou d'imbriquer dans le tableau d'origine, l'ensemble se décompose :)

Espérons que cela aidera quelqu'un dans le futur. C'est un mais adapté à mes besoins mais sera transféré à n'importe quelle structure d'arbre. Je suppose que le faire fonctionner efficacement avec un ensemble imbriqué serait cool, mais comme une barre d'index n'a généralement qu'un ou deux niveaux de profondeur, la récursivité ne deviendra pas incontrôlable.