Checking if an attribute changed after commit in Rails
I do not know if there is any better way, but I would do:
if @item.previous_changes.has_key?('name')
# Name has been changed.
end
Rails, using the dirty or changed? flag with after_commit
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
.
Rails after commit condition
Got it. Called another callback before_update and self.status_changed? value is stored in a flag as @flag = self.status_changed?
Thanks to this article - http://axonflux.com/offlining-denormalized-tasks-gotchas-with-off.
Also cheers to Dave Newton for the kind help.
Prevent infinite loop when updating attributes within after_commit, :on = :create
You can use the method update_column
that will skip all callbacks of your model:
self.update_column(:filename, filename)
Or you could use the method update_all
, wich follows the same behavior
self.class.where('id = ?', self.id).update_all(:filename => filename)
And last but not least, my personal favorite:
self.filename = filename
self.send(:update_without_callbacks)
This one makes it pretty clear that all callbacks are been ignored, what is very helpful
Also, as a different alternative, you coud use after_create
instead of after_commit
if you want to run the generate
method only when a new record is saved
Tracking model changes in after_commit :on = :create callback
You can't use the rails changed?
method, as it will always return false. To track changes after the transaction is committed, use the previous_changes
method. It will return a hash with attribute name as key. You can can then check if your attribute_name is in the hash:
after_commit :foo
def foo
if previous_changes[attribute_name]
#do your task
end
end
Related Topics
Rails Email Error - 530-5.5.1 Authentication Required
How to Run Ruby on Rails with Ruby 1.9X
Rails, How to Render a View/Partial in a Model
Rails Model Name Conflict with Included Gem
Ruby 'Pg' Gem Linking to Wrong Copy of Libpq.5.Dylib (On Osx)
Export Content of a SQLite3 Table in CSV
How to Submit Polymorphic Comments on Feed? [Error]
Unknown Ruby Interpreter Version (Do Not Know How to Handle): Ruby_Version
M Hartl's Ruby on Rails Tutorial Chapter 5 Custom Title on Home Page
Why 6.84 - 3.6 == 3.2399999999999998
Actioncontroller::Routingerror (No Route Matches [Put] ) for Ajax Call
Does Objective-C Support Mixin Like Ruby
How to Reference Global Variables and Class Variables