Führen Sie einen Rückruf nur aus, wenn sich ein Attribut in Rails geändert hat

92

Ich habe die folgende Zuordnung in meiner App:

# Page 
belongs_to :status

Ich möchte einen Rückruf immer dann ausführen, wenn sich der status_idvon a pagegeändert hat.

Wenn es also page.status_idvon 4 auf 5 geht, möchte ich das fangen können.

Wie geht das?

Hommer Smith
quelle

Antworten:

194

Schienen 5.1+

class Page < ActiveRecord::Base
  before_save :do_something, if: :will_save_change_to_status_id?

  private

  def do_something
    # ...
  end
end

Das Commit, das ActiveRecord :: Dirty geändert hat, ist hier: https://github.com/rails/rails/commit/16ae3db5a5c6a08383b974ae6c96faac5b4a3c81

Hier ist ein Blog-Beitrag zu diesen Änderungen: https://www.ombulabs.com/blog/rails/upgrades/active-record-5-1-api-changes.html

Hier ist die Zusammenfassung, die ich für mich zu den Änderungen an ActiveRecord :: Dirty in Rails 5.1+ gemacht habe:

ActiveRecord :: Dirty

https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Dirty.html

Vor dem Speichern (OPTIONALE ÄNDERUNG)

Nach dem Ändern eines Objekts und vor dem Speichern in der Datenbank oder innerhalb des before_saveFilters:

  • changes sollte jetzt sein changes_to_save
  • changed? sollte jetzt sein has_changes_to_save?
  • changed sollte jetzt sein changed_attribute_names_to_save
  • <attribute>_change sollte jetzt sein <attribute>_change_to_be_saved
  • <attribute>_changed? sollte jetzt sein will_save_change_to_<attribute>?
  • <attribute>_was sollte jetzt sein <attribute>_in_database

Nach dem Speichern (BREAKING CHANGE)

Nach dem Ändern eines Objekts und nach dem Speichern in der Datenbank oder innerhalb des after_saveFilters:

  • saved_changes(ersetzt previous_changes)
  • saved_changes?
  • saved_change_to_<attribute>
  • saved_change_to_<attribute>?
  • <attribute>_before_last_save

Schienen <= 5,0

class Page < ActiveRecord::Base
  before_save :do_something, if: :status_id_changed?

  private

  def do_something
    # ...
  end
end

Dies nutzt die Tatsache, dass der before_saveRückruf basierend auf dem Rückgabewert eines Methodenaufrufs bedingt ausgeführt werden kann. Die status_id_changed?Methode stammt von ActiveModel :: Dirty , mit der wir überprüfen können, ob sich ein bestimmtes Attribut geändert hat, indem wir einfach _changed?an den Attributnamen anhängen .

Wann die do_somethingMethode aufgerufen werden soll, hängt von Ihren Anforderungen ab. Dies kann before_saveoder after_saveeiner der definierten ActiveRecord :: Callbacks sein .

pdobb
quelle
4
Diese Lösung ist in neueren Versionen veraltet.
Mateus Luiz
6
Aktualisiert mit Rails 5.1+ Info.
pdobb
15

Das attribute_changed?ist in Rails 5.1 veraltet, jetzt einfach verwenden will_save_change_to_attribute?.

Weitere Informationen finden Sie in diesem Problem .

Mateus Luiz
quelle