Partial updates: why should validations run even if record won't be saved?

Is it a bug that when partial updates are on validations are run even though the record is not going to save? This obviously cuts down on performance especially with validations like validates_uniqueness_of that hit the db. See the console for the database hit on the validation even though the record was never going to be saveed...

# account.rb class Account < ActiveRecord::Base validates_presence_of :subdomain validates_uniqueness_of :subdomain end

~/dev/topsecret(master) $ ./script/console Loading development environment (Rails 2.0.991) ActiveRecord::Base.logger = >> ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Base.logger = Logger.new(STDOUT)

=> #<Logger:0x1978244 @formatter=nil, @default_formatter=#<Logger::Formatter:0x1978118 @datetime_format=nil>, @progname=nil, @level=0, @logdev=#<Logger::LogDevice:0x19763e0 @mutex=#<Logger::LogDevice::LogDeviceMutex:0x197632c @mon_owner=nil, @mon_waiting_queue=, @mon_entering_queue=, @mon_count=0>, @dev=#<IO:0x2e7d4>, @shift_size=nil, @shift_age=nil, @filename=nil>>

a = Account.first

SQL (0.000233) SET NAMES 'utf8' SQL (0.000148) SET SQL_AUTO_IS_NULL=0 Account Load (0.095192) SELECT * FROM `accounts` LIMIT 1 Account Columns (0.075976) SHOW FIELDS FROM `accounts` => #<Account id: 1049686059, subdomain: "foobar", token: "5e5160dbb2e9712af96a94348711b5320273bbfb", password: "9849291", created_at: "2008-05-20 16:18:15", updated_at: "2008-05-21 18:02:06">

a.changed?

=> false

a.save

SQL (0.000187) BEGIN SQL (0.020573) SELECT `subdomain` FROM `accounts` WHERE (`accounts`.subdomain = 'foobar' AND `accounts`.id <> 1049686059) SQL (0.003990) COMMIT => true

Let me know if this is indeed a bug and I'll file a proper bug report and work up a fix. I just wanted to bring this up sooner rather than later as I understand 2.1 is releasing soon.

Best,

Zack Chandler http://depixelate.com

Let me know if this is indeed a bug and I'll file a proper bug report and work up a fix. I just wanted to bring this up sooner rather than later as I understand 2.1 is releasing soon.

I can definitely see how it might be a little annoying, but I'm not sure that a quick fix is prudent this late in the release cycle. There are a few hairy issues with callbacks:

before_save and friends, should they still fire? What about the other callbacks? What if those callbacks were going to change attributes? Basically we can't tell until the last minute whether or not a record is changed, without introducing some bugs.

Let me know if this is indeed a bug and I'll file a proper bug report and work up a fix. I just wanted to bring this up sooner rather than later as I understand 2.1 is releasing soon.

I can definitely see how it might be a little annoying, but I'm not sure that a quick fix is prudent this late in the release cycle. There are a few hairy issues with callbacks:

before_save and friends, should they still fire? What about the other callbacks? What if those callbacks were going to change attributes? Basically we can't tell until the last minute whether or not a record is changed, without introducing some bugs.

I agree this is too late in the release cycle for 2.1.

Still the only way that callbacks would affect attributes would be if they were acting on non-attribute related information like an association's attributes or the current time, etc. This would seem to affect a very, very small percentage of models and therefore it would make sense for Rails to make not running validations a "sensible default" IMO.

Best,

Zack

I agree this is too late in the release cycle for 2.1.

Still the only way that callbacks would affect attributes would be if they were acting on non-attribute related information like an association's attributes or the current time, etc. This would seem to affect a very, very small percentage of models and therefore it would make sense for Rails to make not running validations a "sensible default" IMO.

I disagree, many people (i.e. me) hash their passwords in a before_save or before_validate callback, so until those are run the hashed_password attribute is unchanged.

Still the only way that callbacks would affect attributes would be if they were acting on non-attribute related information like an association's attributes or the current time, etc. This would seem to affect a very, very small percentage of models and therefore it would make sense for Rails to make not running validations a "sensible default" IMO.

I disagree, many people (i.e. me) hash their passwords in a before_save or before_validate callback, so until those are run the hashed_password attribute is unchanged.

Yes - hashing password is a good case against trying to further optimizing the db hits with partial updates.

I suppose those of us looking to squeeze a bit more performance out can just do:

@obj.save if @obj.changed?

Best,

Zack