2016-07-07 17 views
1

Ich weiß, dass die allgemeine Reihenfolge, in der Modelle gespeichert werden, zuerst das tiefste Kind ist und dann schrittweise bis zum Elternteil. Aber ich frage mich, in Bezug auf andere Rückrufe, kommt es etwas entlang der Linien von:Rails in welcher Reihenfolge finden Modell-Callbacks für verschachtelte Eltern/Kind-Modelle statt?

ChildA - before validation 
ChildB - before validation 
Parent - before validation 

ChildA - after validation 
ChildB - after validation 
Parent - after validation 

ChildA - before save 
ChildB - before save 
Parent - before save 

... 

oder entlang der Linien von:

ChildA - before validation 
ChildA - after validation 
ChildA - before save 
... 

ChildB - before validation 
ChildB - after validation 
ChildB - before save 
... 

Parent - before validation 
Parent - after validation 
Parent - before save 
... 

Der Grund, dies ist wichtig, dass ich Rückrufe haben Das Anpassen von Attributen und die Anpassungsfähigkeit eines Attributs in einem Modell hängt von den Attributen anderer Modelle ab.

Ein Beispiel dafür ist, dass ich die Parent auf Auto-Set seiner status Attribute will Complete wenn ChildA und child B's Status attributes are both komplette and the children are both valid` sein.

Ich habe versucht, dies mit puts Aussagen zu testen, aber anscheinend führt das zu einem seltsamen Verhalten (siehe diese Frage: Nested form validation statements repeating multiple times), und ich fürchte, es ist nicht repräsentativ.

Ich lese jeden Fall die Rails Guides, aber ich bin vielleicht blind, weil ich nicht einen Hinweis auf diese überall sehen war ...

+0

Haben Sie jemals die Antwort darauf gefunden? – geoboy

Antwort

0

diese Art von Zustandsmaschinenlogik in Rückrufe sein könnte verlockend es zwar setzen, macht einen schwer verständlichen Code. Ziehen Sie stattdessen eine dedizierte Methode in Betracht, mit der Sie Ihre Daten einfacher erfassen und mutieren können.

Dies würde auch bei Datenkonsistenz und Tests helfen, wie in this blog post beschrieben.

+0

Danke! Etwas in der Zukunft zu berücksichtigen, für jetzt, nur wirklich etwas schnell und schmutzig – james

0

Interessante Frage. Standardmäßig wird der im Parent definierte Callback zuerst ausgeführt. prepend: true Option können Sie dieses Verhalten einstellen.

Siehe Abschnitt "Rückrufe bestellen" unter Rails API. Es lohnt sich auch, den Abschnitt "Vererbbare Rückrufwarteschlangen" zu überprüfen, da die Neudefinition einer Methode nicht mit der Verwendung von Makros identisch ist.

P.S. Alle oben genannten gelten mindestens für Version 4.2.5.2

0

Durch das Experimentieren mit Schienen habe ich festgestellt, dass das Elternteil zuerst validiert wird und dann Kind, aber kein Rails-Core-Member darüber ausgesprochen haben.

Deshalb sollten Sie Logik Eltern bewegen kann:

class Sale 
    has_many :details 
    before_validation :evaluate_details 
    # validations 

    def evaluate_details 
    self.details.each do |detail| 
     detail.generate_info 
     detail.items.each do |item| 
     item.dance 
     end 
    end 
    end 
end 

class Detail 
    belongs_to :sale 
    has_many :items 
    # validations 

    def generate_info 
    # Do things 
    end 
end 

class Item 
    belongs_to :detail 
    # validations 

    def dance 
    # Dancing 
    end 
end 

Dies verhindert, dass mehrere Ausführungen und verwaltet die Ausführungsreihenfolge.

PD: Sie können auch den Rückruf before_validation vermeiden und die Methode manuell aufrufen.