Caching bei ActiveRecord / oder: [better nested set] Hierachie rendern und alphabetisch sortieren?

ja hallo erstmal,…

also… bis vor kurzem habe ich ich acts_as_tree verwendet und eine
hierachische Struktur rekursiv gerendert (Rails ist 1.2.6).

D.h. Etwa so:
http://pastie.caboo.se/168690

Nun bin auch auf better_nested_set umgestiegen, indem man das
Menü bekanntlich
iterativ bauen kann:
http://opensource.symetrie.com/trac/better_nested_set/wiki/RecursiveMenu

Jedoch hat diese Lösung das Problem, dass ich keinen Weg sehe sie
alphabetisch
zu sortien.

Also war meine nächste Idee, den ganzen Baum einfach zu laden (wie im
iterativen Beipiel Beispiel) zu cachen
children_ids = self.all_children.map { |c| c.id}
children = Holding.find(children_ids,:include => [:a,:b,…], :order
=> :name )
und dann die wieder rekursiv zu rendern.
Jedoch für der o.g. render-code dazu,
(insb. die er Aufruf tree.children), dass (wie im acts_as_tree-Fall)
Für jedes Element ein SQL-Query zum Laden der Kinder benutzt wird (anstatt
die
vorher geladene Objekte aus dem Cache zu holen - trotz production-mode)
und
die ganze Anwendung wieder langsam wird…
Ein versuch, den Cache “naiv” einzuschalten und einfach
tree.children(true) zu schreibe wurde monierte, da children (anders als
bei
acts_as_tree) keine Argumente habe darf.

Gibt es irgendeinen einfachen Weg, irgendwelches Caches in Better nested
Set
oder ActiveRecord zu nutzen?
Mein derzeitiger Weg ist, selber einen Cache-Hash im Wurzel-Objekt zu
bauen -
aber das ist ziemlich hässlich…

Danke,
Keep smiling
yanosz

Hallo Jan,

ich weiß nicht, ob Du mittlerweile eine gute Lösung gefunden hast.
Mein (naiver) Ansatz wäre, eine SQL-Abfrage abzusetzen, die alle Kinder
bzw.
deren Assoziationen selbst aus der Datenbank ausliest. Dabei helfen Dir
die
Spalten “lft” und “rgt” (oder wie die beiden Spalten bei Dir heißen):
Sie
geben die obere und untere ID-Schranke an. Alle Kinder liegen zwischen
diesen beiden Werten.

Ich hoffe, das hilft Dir weiter…

Grüße
Nicolai

Am 21.03.08 schrieb Jan L. [email protected]:

ja hallo erstmal,…

Am Samstag, 22. März 2008 schrieb Codeblogger:

Hallo Jan,

ich weiß nicht, ob Du mittlerweile eine gute Lösung gefunden hast.
Mein (naiver) Ansatz wäre, eine SQL-Abfrage abzusetzen, die alle Kinder
bzw. deren Assoziationen selbst aus der Datenbank ausliest. Dabei helfen
Dir die Spalten “lft” und “rgt” (oder wie die beiden Spalten bei Dir
heißen): Sie geben die obere und untere ID-Schranke an. Alle Kinder liegen
zwischen diesen beiden Werten.

Ich hoffe, das hilft Dir weiter…

Hmm… das ist klar.
Ich finde die Idee aber nicht wirklich besser als einen eigenen Cache zu
bauen - ich suchte eigentlich nach einer Option im Framework um
ActiveRecord
einen so großen Datenbank-Cache zu geben, dass alles darin landet…

Bislang bau ich mir meinen Cache etwa so:
self.all_children.each do |child|
@child_cache[child.parent_id] = [] if
@child_cache[child.parant_id].nil?
@child_cache[child.parent_id] << child
end

Dadurch habe ich den ganzen (Teil-)Baum im Ram und kann - wann immer ich
rekursiv arbeiten will -, den @child_cache dazu nutzen.

(Was mir daran sogar gar nicht mal so schlecht gefällt, ist dass man
sehr
einfach fachliche Constraints an den Cache stellen kann (z.B. maximale
Tiefe,
in dieser Anfrage zu ignorierende children)

Alles Gute
Jan