Ich verwende das awesome_nested_set
Plugin in meinem Rails-Projekt. Ich habe zwei Modelle, die so aussehen (vereinfacht):
Der Baum in der Datenbank ist wie erwartet aufgebaut. Alle Werte von parent_id
, lft
und rgt
sind korrekt. Der Baum hat mehrere Wurzelknoten (was natürlich in awesome_nested_set
erlaubt ist).
Nun möchte ich alle Kategorien eines bestimmten Kunden in einer korrekt sortierten Baumstruktur darstellen: zum Beispiel verschachtelte <ul>
-Tags. Dies wäre nicht zu schwierig, aber ich brauche es effizient (je weniger SQL Abfragen desto besser).
Update: Es wurde herausgefunden, dass es möglich ist, die Anzahl der Kinder für einen bestimmten Knoten in der Baumstruktur ohne weitere SQL-Abfragen zu berechnen: number_of_children = (node.rgt - node.lft - 1)/2
. Dies löst das Problem nicht, aber es kann sich als hilfreich erweisen.
Es wäre schön, wenn verschachtelte Sets bessere Funktionen hätten, nicht wahr?
Der Trick, den Sie entdeckt haben, besteht darin, den Baum aus einem flachen Satz zu erstellen:
siehe unten:
%Vor%Ich habe eine ähnliche Frage beantwortet für php kürzlich (verschachtelte Menge == modifiziertes Vororderbaum-Traversalmodell).
Das Grundkonzept besteht darin, die Knoten bereits geordnet und mit einem Tiefenindikator durch eine SQL-Abfrage zu erhalten. Von dort ist es nur eine Frage des Renderns der Ausgabe über eine Schleife oder Rekursion, so dass es leicht sein sollte, dies in Ruby umzuwandeln.
Ich bin nicht vertraut mit dem awesome_nested_set
Plug-in, aber es könnte bereits eine Option enthalten, um die Tiefe annotiertes, geordnetes Ergebnis zu erhalten, da es eine ziemlich normale Operation / Notwendigkeit ist, wenn verschachtelte Mengen behandelt werden.
Seit September 2009 enthält das geniale verschachtelte Set eine spezielle Methode, um dies zu tun: Zypern
Diese Methode ist viel effizienter als das Aufrufen der Ebene, da keine zusätzlichen Datenbankabfragen erforderlich sind.
Beispiel: Category.each_with_level (Category.root.self_and_descendants) tue | o, level |
Sie müssen einen Teil rekursiv rendern, der sich selbst aufruft. Etwas wie das:
%Vor%Dies ist der Code von Rails 2.3. Sie müssen die Routen aufrufen und das Teil explizit vorher benennen.
_tree.html.eb
%Vor%_item.html.erb
%Vor%Sie können auch sortieren:
%Vor%aber in diesem Fall sollten Sie diese Zeile ENTFERNEN:
%Vor%Ich konnte die angenommene Antwort wegen der alten Version von Ruby, für die es geschrieben wurde, nicht annehmen. Hier ist die Lösung für mich:
%Vor%Es wird durch die Verwendung der optionalen Tiefeninformation vereinfacht. (Vorteil dieses Ansatzes ist, dass die Eingabesatz nicht die gesamte Struktur zu den Blättern sein muss.)
Eine komplexere Lösung ohne Tiefen finden Sie auf GitHub Wiki des Edelsteins:
Tags und Links sql ruby ruby-on-rails activerecord nested-sets