14

I heard rails has a dirty/change flag. Is it possible to use that in the after_commit callback?

In my user model I have:

after_commit :push_changes

In def push_changes I would like a way to know if the name field changed. Is that possible?

Yarin
  • 173,523
  • 149
  • 402
  • 512
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012

3 Answers3

36

You can use previous_changes in after_commit to access a model's attribute values from before it was saved.

see this post for more info: after_commit for an attribute

Community
  • 1
  • 1
Yoni
  • 624
  • 5
  • 15
7

You can do a few things to check...

First and foremost, you can check an individual attribute as such:

user = User.find(1)
user.name_changed? # => false
user.name = "Bob"
user.name_changed? # => true

But, you can also check which attributes have changed in the entire model:

user = User.find(1)
user.changed     # => []
user.name = "Bob"
user.age = 42
user.changed     # => ['name', 'age']

There's a few more things you can do too - check out http://api.rubyonrails.org/classes/ActiveModel/Dirty.html for details.

Edit:

But, given that this is happening in an after_commit callback, the model has already been saved, meaning knowledge of the changes that occurred before the save are lost. You could try using the before_save callback to pick out the changes yourself, store them somewhere, then access them again when using after_commit.

BaronVonBraun
  • 4,285
  • 23
  • 23
  • 3
    Right, sorry, missed that part of it. After saving the model the changed attributes are wiped out, so this would be pretty useless... Could you yourself store the changed attributes using `before_save`, for instance, and then retrieve them afterwards? – BaronVonBraun Aug 23 '11 at 01:25
  • 12
    `changed?`/`changes` will work in **after_save**, but not **after_commit**. Instead, you can use `previous_changes` in **after_commit**- see @Jonathan's [answer](http://stackoverflow.com/a/16823712/165673) – Yarin Feb 06 '15 at 19:02
4

Since Rails 5.1, in after_commit you should use saved_change_to_attribute?

Ref: Rails 5.1.1 deprecation warning changed_attributes

Fangxing
  • 5,716
  • 2
  • 49
  • 53