Je configure un rappel after_save dans mon observateur de modèle pour envoyer une notification uniquement si l' attribut publié du modèle est passé de faux à vrai. Depuis des méthodes telles que changé? ne sont utiles qu'avant l'enregistrement du modèle, la façon dont j'essaie actuellement (et sans succès) de le faire est la suivante:
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
Quelqu'un a-t-il des suggestions sur la meilleure façon de gérer cela, de préférence en utilisant les rappels d'observateur de modèle (afin de ne pas polluer le code de mon contrôleur)?
after_update
appel:after_update :send_notification_after_change, if: -> { published_changed? }
saved_change_to_published?
ousaved_change_to_published
récupérer la modification pendant le rappelPour ceux qui veulent connaître les modifications qui viennent d'être apportées lors d'un
after_save
rappel:Rails 5.1 et plus
Rails <5,1
Voir également: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
la source
after_save
callback,self.changed?
esttrue
etself.attribute_name_changed?
est aussitrue
, maisself.previous_changes
renvoie un hachage vide.saved_changes
dans lesafter_save
rappelsÀ tous ceux qui verront cela plus tard, comme il est actuellement (août 2017) en tête de Google: Il convient de mentionner que ce comportement sera modifié dans Rails 5.2 et qu'il a des avertissements de dépréciation à partir de Rails 5.1, car ActiveModel :: Dirty a un peu changé .
Qu'est-ce que je change?
Si vous utilisez la
attribute_changed?
méthode dans lesafter_*
-callbacks, vous verrez un avertissement comme:Comme il le mentionne, vous pouvez résoudre ce problème facilement en remplaçant la fonction par
saved_change_to_attribute?
. Ainsi, par exemple,name_changed?
devientsaved_change_to_name?
.De même, si vous utilisez
attribute_change
pour obtenir les valeurs avant-après, cela change également et lance ce qui suit:Encore une fois, comme il le mentionne, la méthode change le nom vers
saved_change_to_attribute
lequel retourne["old", "new"]
. ou usesaved_changes
, qui renvoie toutes les modifications, et celles-ci sont accessibles en tant quesaved_changes['attribute']
.la source
attribute_was
méthodes: utilisezsaved_change_to_attribute
plutôt.Si vous pouvez le faire à la
before_save
place deafter_save
, vous pourrez utiliser ceci:il renvoie un tableau de toutes les colonnes modifiées de cet enregistrement.
vous pouvez aussi utiliser:
qui renvoie un hachage de colonnes qui ont changé et des résultats avant et après sous forme de tableaux
la source
after_
rappel, ce qui était en fait l'objet de la question. La réponse de @ jacek-głodek ci-dessous est la bonne.before_save
self.changed
peut être utilisé dans lesafter_save
rappels.self.changed
est un tableau de chaînes! (Pas de symboles!)["attr_name", "other_attr_name"]
La réponse «sélectionnée» n'a pas fonctionné pour moi. J'utilise les rails 3.1 avec CouchRest :: Model (basé sur Active Model). Les
_changed?
méthodes ne retournent pas true pour les attributs modifiés dans leafter_update
hook, uniquement dans lebefore_update
hook. J'ai pu le faire fonctionner en utilisant le (nouveau?)around_update
Hook:la source
vous pouvez ajouter une condition
after_update
similaire pour:il n'est pas nécessaire d'ajouter une condition dans la
send_notification
méthode elle-même.la source
Vous ajoutez simplement un accesseur qui définit ce que vous modifiez
la source