Ich richte in meinem Modellbeobachter einen after_save-Rückruf ein, um nur dann eine Benachrichtigung zu senden, wenn das veröffentlichte Attribut des Modells von false in true geändert wurde. Da Methoden wie geändert? sind nur nützlich, bevor das Modell gespeichert wird. Ich versuche dies derzeit (und erfolglos) wie folgt:
def before_save(blog)
@og_published = blog.published?
end
def after_save(blog)
if @og_published == false and blog.published? == true
Notification.send(...)
end
end
Hat jemand Vorschläge, wie dies am besten gehandhabt werden kann, vorzugsweise mithilfe von Rückrufen von Modellbeobachtern (um meinen Controller-Code nicht zu verschmutzen)?
quelle
after_update
Aufruf die Bedingung hinzufügen :after_update :send_notification_after_change, if: -> { published_changed? }
saved_change_to_published?
odersaved_change_to_published
Für diejenigen, die wissen möchten, welche Änderungen gerade in einem
after_save
Rückruf vorgenommen wurden:Schienen 5.1 und höher
Schienen <5.1
Siehe auch: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
quelle
after_save
Rückruf verwenden,self.changed?
isttrue
undself.attribute_name_changed?
ist dies auchtrue
, gibt aberself.previous_changes
einen leeren Hash zurück.saved_changes
inafter_save
RückrufenFür alle, die dies später sehen, da es derzeit (August 2017) über Google steht: Es ist erwähnenswert, dass dieses Verhalten in Rails 5.2 geändert wird und ab Rails 5.1 Verfallswarnungen enthält , da sich ActiveModel :: Dirty etwas geändert hat .
Was ändere ich?
Wenn Sie die
attribute_changed?
Methode in denafter_*
Rückrufen verwenden, wird eine Warnung wie folgt angezeigt:Wie bereits erwähnt, können Sie dies leicht beheben, indem Sie die Funktion durch ersetzen
saved_change_to_attribute?
. So zum Beispielname_changed?
wirdsaved_change_to_name?
.Wenn Sie die verwenden
attribute_change
, um die Vorher-Nachher-Werte abzurufen, ändert sich dies ebenfalls und löst Folgendes aus:Wie bereits erwähnt, ändert die Methode den Namen, zu
saved_change_to_attribute
dem sie zurückkehrt["old", "new"]
. oder usesaved_changes
, das alle Änderungen zurückgibt und auf die als zugegriffen werden kannsaved_changes['attribute']
.quelle
attribute_was
Methoden enthält: Verwenden Siesaved_change_to_attribute
stattdessen.Wenn Sie dies
before_save
anstelle von tun könnenafter_save
, können Sie Folgendes verwenden:Es gibt ein Array aller geänderten Spalten in diesem Datensatz zurück.
Sie können auch verwenden:
Dies gibt einen Hash von Spalten zurück, die sich geändert haben und vor und nach den Ergebnissen als Arrays
quelle
after_
Rückruf nicht funktionieren , worum es bei der Frage eigentlich ging. Die Antwort von @ jacek-głodek unten ist die richtige.before_save
self.changed
kann inafter_save
Rückrufen verwendet werden.self.changed
eine Reihe von Zeichenfolgen ist! (Keine Symbole!)["attr_name", "other_attr_name"]
Die "ausgewählte" Antwort hat bei mir nicht funktioniert. Ich verwende Rails 3.1 mit CouchRest :: Model (basierend auf Active Model). Die
_changed?
Methoden geben nicht true für geänderte Attribute imafter_update
Hook zurück, sondern nur imbefore_update
Hook. Ich konnte es mit dem (neuen?)around_update
Haken zum Laufen bringen:quelle
Sie können dem
after_update
Gleichen eine Bedingung hinzufügen, so:Es ist nicht erforderlich, eine Bedingung innerhalb der
send_notification
Methode selbst hinzuzufügen .quelle
Sie fügen einfach einen Accessor hinzu, der definiert, was Sie ändern
quelle