after_commit for an attribute

Old question, but this is one method that I've found that might work with the after_commit callback (working off paukul's answer). At least, the values both persist post-commit in IRB.

after_commit :callback, 
  if: proc { |record| 
    record.previous_changes.key?(:attribute) &&
      record.previous_changes[:attribute].first != record.previous_changes[:attribute].last
  }

Answering this old question because it still pops up in search results

you can use the previous_changes method which returnes a hash of the format:

{ "changed_attribute" => ["old value", "new value"] }

it's what changes was until the record gets actually saved (from active_record/attribute_methods/dirty.rb):

  def save(*) #:nodoc:
    if status = super
      @previously_changed = changes
      @changed_attributes.clear
      # .... whatever goes here

so in your case you can check for previous_changes.key? "your_attribute" or something like that


I don't think you can do it in after_commit

The after_commit is called after the transaction is commited Rails Transactions

For example in my rails console

> record = MyModel.find(1)
=> #<MyModel id: 1, label: "test", created_at: "2011-08-19 22:57:54", updated_at: "2011-08-19 22:57:54">
> record.label = "Changing text"
=> "Changing text"
> record.label_changed?
=> true
> record.save
=> true
> record.label_changed?
=> false 

Therefore you won't be able to use the :if condition on after_commit because the attribute will not be marked as changed anymore as it has been saved. You may need to track whether the field you are after is changed? in another callback before the record is saved?