Mit Active, ist es eine Möglichkeit, die alten Werte eines Datensatzes zu erhalten während after_update

StackOverflow https://stackoverflow.com/questions/607069

Frage

Setup ein einfaches Beispiel: ein. Ich habe 1 Tisch (Totals) bekommt, das die Summe der amount Spalte jeden Datensatz in einer zweiten Tabelle (Things) hält

Wenn ein thing.amount aktualisiert wird, würde Ich mag einfach den Unterschied zwischen dem alten Wert hinzufügen und den neuen Wert total.sum.

Im Moment self.amount während before_update und das Hinzufügen von self.amount während after_update ich subtrahieren. Dies stellt viel zu viel Vertrauen in das Update erfolgreich.

Constraint:. Ich will nicht einfach die Summe aller Transaktionen neu zu berechnen

Frage: Ganz einfach, ich möchte den ursprünglichen Wert während eines after_update Rückruf zuzugreifen. Welche Möglichkeiten haben Sie kommen mit tun?

Update: Ich bin mit Luke Francl Idee geht. Während eines after_update Rückruf haben Sie noch Zugriff auf die self.attr_was Werte das ist genau das, was ich wollte. Ich habe auch beschlossen mit einer after_update Umsetzung zu gehen, weil ich diese Art von Logik im Modell beibehalten möge. Auf diese Weise, egal wie ich mich entscheide, Transaktionen in der Zukunft zu aktualisieren, ich weiß, dass ich die Summe der Transaktionen korrekt bin zu aktualisieren. Vielen Dank an alle für Ihre Implementierung Vorschläge.

War es hilfreich?

Lösung

Ditto, was jeder sagt über Transaktionen.

Das sagte ...

Active wie von Rails 2.1 verfolgt die Attributwerte eines Objekts. Also, wenn Sie ein Attribut total haben, erhalten Sie eine total_changed? Verfahren und eine total_was Methode, die den alten Wert zurückgibt.

Es gibt keine Notwendigkeit, etwas zu Ihrem Modell hinzuzufügen Spur davon zu halten mehr.

Update: Hier ist die Dokumentation für ActiveModel :: Schmutzige wie gewünscht geplant.

Andere Tipps

Einige andere Leute sind zu erwähnen, all dies in einer Transaktion wickeln, aber ich denke, dass für Sie getan hat; Sie müssen nur die Rollback ausgelöst wird, um eine Ausnahme für Fehler in den after_ * Rückrufe zu erhöhen.

Siehe http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

  

Die gesamte Rückrufkette eines speichern, speichern !, oder Anruf läuft innerhalb einer Transaktion zerstören. Dazu gehören after_ * Haken. Wenn alles gut geht ein COMMIT ausgeführt wird, sobald die Kette abgeschlossen ist.

     

Wenn ein before_ * Rückruf, um die Aktion ein ROLLBACK abgebrochen ausgegeben. Sie können auch eine ROLLBACK auslösen eine Ausnahme in einem der Rückrufe erhöhen, einschließlich after_ * Haken. Beachten Sie jedoch, dass in diesem Fall der Kunde dessen bewusst sein muss, weil ein gewöhnlicher sparen solche Ausnahme erhöhen statt leise Rückkehr falsch.

Anfügen „_was“ zu Ihrem Attribut geben Sie den vorherigen Wert, bevor die Daten zu speichern.

Diese Methoden schmutzigen Methoden Methoden.

Cheers!

Um alle geänderten Felder zu erhalten, mit ihren alten und neuen Werten, die jeweils:

person = Person.create!(:name => 'Bill')
person.name = 'Bob'
person.save
person.changes        # => {"name" => ["Bill", "Bob"]}

Active :: Schmutzige ist ein Modul, das in Activerecord für die Verfolgung errichtet wird Attributänderungen. So können Sie thing.amount_was verwenden, um den alten Wert zu erhalten.

Fügen Sie diese auf Ihrem Modell:

def amount=(new_value)
    @old_amount = read_attribute(:amount)
    write_attribute(:amount,new_value)
end

Dann in Ihrem after_update Code verwenden @old_amount.

Zunächst sollten Sie dies in einer Transaktion tun, um sicherzustellen, dass Ihre Daten zusammen geschrieben wird.

Um Ihre Frage zu beantworten, können Sie nur eine Membervariable auf den alten Wert im BEFORE_UPDATE gesetzt, die Sie dann Zugriff im after_update, aber dies nicht eine sehr elegante Lösung.

Idee 1: Wickeln Sie das Update in einer Datenbanktransaktion, so dass, wenn die Aktualisierung Ihrer Summentabelle nicht nicht geändert wird: Active Transaktionen docs

Idee 2: Stash den alten Wert in @old_total während der BEFORE_UPDATE

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top