I'm setting up an after_save callback in my model observer to send a notification only if the model's published attribute was changed from false to true. Since methods such as changed? are only useful before the model is saved, the way I'm currently (and unsuccessfully) trying to do so is as follows:
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
Does anyone have any suggestions as to the best way to handle this, preferably using model observer callbacks (so as not to pollute my controller code)?
To anyone seeing this later on, as it currently (Aug. 2017) tops google: It is worth mentioning, that this behavior will be altered in Rails 5.2, and has deprecation warnings as of Rails 5.1, as ActiveModel::Dirty changed a bit.
What do I change?
If you're using
attribute_changed?
method in theafter_*
-callbacks, you'll see a warning like:As it mentions, you could fix this easily by replacing the function with
saved_change_to_attribute?
. So for example,name_changed?
becomessaved_change_to_name?
.Likewise, if you're using the
attribute_change
to get the before-after values, this changes as well and throws the following:Again, as it mentions, the method changes name to
saved_change_to_attribute
which returns["old", "new"]
. or usesaved_changes
, which returns all the changes, and these can be accessed assaved_changes['attribute']
.For those who want to know the changes after save, you should use
this works like
model.change
but it works still aftermodel.save
, etc. I found this information useful so maybe you will too.In Rails 5.1+ this is deprecated. Use
saved_changes
inafter_save
callbacks instead.In case you can do this on
before_save
instead ofafter_save
, you'll be able to use this:it returns an array of all changed columns in this record.
you can also use:
which returns a hash of columns that changed and before and after results as arrays
you can add a condition to the
after_update
like so:there's no need to add a condition within the
send_notification
method itself.The "selected" answer didn't work for me. I'm using rails 3.1 with CouchRest::Model (based on Active Model). The
_changed?
methods don't return true for changed attributes in theafter_update
hook, only in thebefore_update
hook. I was able to get it to work using the (new?)around_update
hook:You just add an accessor who define what you change