I came across this issue the other day at work, and I’m not really sure how I feel about it. It doesn’t necessarily seem right or wrong, but was definitely unintuitive for me…

Since Rails 2.1, we have had dirty object checking, which prevents ActiveRecord from saving an object if if hasn’t changed:

>> person = Person.first
  Person Load (0.9ms)   SELECT * FROM "people" LIMIT 1
=> #

>> person.save
=> true

>> person.nickname = "nick"
=> "nick"

>> person.save
  Person Update (20.6ms)   UPDATE "people" SET "updated_at" = ’2009-08-20 02:31:17′, "nickname" = ‘nick’ WHERE "id" = 1
=> true

That part is good, but what happens when you have a callback defined?

>> Person.after_save { puts ‘After save…’ }
=> [# , @kind=:after_save, @options={}>]

>> person.nickname = nil
=> nil

>> person.save
  Person Update (2.4ms)   UPDATE "people" SET "updated_at" = ’2009-08-20 02:33:21′, "nickname" = NULL WHERE "id" = 1
After save…
=> true

>> person.save
After save…
=> true

As we see there, the callback gets triggered even if the save is short-circuited.

In my trivial example, the behavior isn’t terribly important either way. However, if your callback is doing something relatively expensive it may be pointless (and wasteful) to do that on a clean object. There are certainly situations where you would want it to always trigger, so I guess it’s just one of those things that a developer ought to keep in the back of his mind when coding.

Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

© 2012 Techspeak Suffusion theme by Sayontan Sinha