views:

546

answers:

1

ActiveRecord use to call after_save callback each time save method is called even if the model was not changed and no insert/update query spawned.

This is the default behaviour actually. And that is ok in most cases.

But some of the after_save callbacks are sensitive to the thing that if the model was actually saved or not.

Is there a way to determine if the model was actually saved in the after_save?

I am running the following test code:

class Stage < ActiveRecord::Base
  after_save do
    pp changes
  end
end

s = Stage.first
s.name = "q1"
s.save!
+4  A: 

ActiveRecord use to call after_save callback each time save method is called even if the model was not changed and no insert/update query spawned.

ActiveRecord executes :after_save callbacks each time the record is successfully saved regardless it was changed.

# record invalid, after_save not triggered
Record.new.save

# record valid, after_save triggered
r = Record.new(:attr => value)

# record valid and not changed, after_save triggered
r.save

What you want to know is if the record is changed, not if the record is saved. You can easily accomplish this using record.changed?

class Record

  after_save :do_something_if_changed

  protected

  def do_something_if_changed
    if changed?
      # ...
    end
  end
end
Simone Carletti
changed? always false after save!
Bogdan Gusiev
Did you try? `changed?` status should be reset after the last `after_save` callback is executed.
Simone Carletti
Yes, with ActiveRecord 2.3.4
Bogdan Gusiev
Could somebody confirm that it works on his side?
Bogdan Gusiev
I'm testing it with Rails 2.3.5 and it worked for me. Update your question with your example so that I can test it.
Simone Carletti
changed? works in after_save in 2.3.4 as well!
reto
Note: changed? wont be true for 'after_destroy', so take care if the same handler covers both cases.
reto