Exécuter un rappel uniquement si un atsortingbut a changé dans Rails

J’ai l’association suivante dans mon application:

# Page belongs_to :status 

Je veux exécuter un rappel chaque fois que le status_id d’une page a changé.

Donc, si page.status_id va de 4 à 5, je veux pouvoir le saisir.

Comment faire

Rails 5.1+

 class Page < ActiveRecord::Base before_save :do_something, if: :will_save_change_to_status_id? private def do_something # ... end end 

Le commit qui a changé ActiveRecord :: Dirty est ici: https://github.com/rails/rails/commit/16ae3db5a5c6a08383b974ae6c96faac5b4a3c81

Voici un article de blog sur ces changements: https://www.ombulabs.com/blog/rails/upgrades/active-record-5-1-api-changes.html

Rails <5.0

 class Page < ActiveRecord::Base before_save :do_something, if: :status_id_changed? private def do_something # ... end end 

Cela utilise le fait que le rappel before_save peut s'exécuter conditionnellement en fonction de la valeur de retour d'un appel de méthode. Le status_id_changed? méthode vient d' ActiveModel :: Dirty , qui nous permet de vérifier si un atsortingbut spécifique a changé en ajoutant simplement _changed? au nom de l'atsortingbut.

Lorsque la méthode do_something doit être appelée, cela dépend de vos besoins. Il peut s'agir de before_save ou after_save ou de l'un des ActiveRecord :: Callback définis .

Essaye ça

 after_validation :do_something, if: ->(obj){ obj.status_id.present? and obj.status_id_changed? } def do_something # your code end 

Référence – http://apidock.com/rails/ActiveRecord/Dirty

L’ atsortingbute_changed? il est obsolète dans Rails 5.1, maintenant utilisez simplement will_save_change_to_atsortingbute? .

Pour plus d’informations:

https://github.com/rails/rails/issues/29035