I want a validation to run before a record gets updated. I know of before_update but I pretty much copy and pasted the first codesnippet out of the api docs.
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
My stripped down model looked then like
class User < ActiveRecord::Base
attr_accessible :email
validates :email, :presence => true
before_save(:on => :update) do
puts "******** before_save on => :update ********"
# do something
end
end
if I go into the console and do create a new entry this callback is being executed on a SQL insert call.
irb(main):001:0> User.new(:email => "test@test.com").save
(0.1ms) begin transaction
******** before_save on => :update ********
SQL (29.1ms) INSERT INTO "users" ("created_at", "email", "first_name", "last_name", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Fri, 30 Mar 2012 00:26:33 UTC +00:00], ["email", "test@test.com"], ["first_name", nil], ["last_name", nil], ["updated_at", Fri, 30 Mar 2012 00:26:33 UTC +00:00]]
(433.1ms) commit transaction
=> true
irb(main):002:0>
I would have expected to see this only on an update call. Can anybody sheed some light on this?
[EDIT]
I just changed the callback into a function call with no change in the outcome. The callback is still executed on create.
class User < ActiveRecord::Base
attr_accessible :email
validates :email, :presence => true
before_save :my_before_update, :on => :update
private
def my_before_update
puts "******** before_save on => :update ********"
# do something
end
end
The output is the same.
Loading development environment (Rails 3.2.2)
irb(main):001:0> User.new(:email => "test@test.com").save
(0.1ms) begin transaction
******** before_save on => :update ********
SQL (28.2ms) INSERT INTO "users" ("created_at", "email", "first_name", "last_name", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Fri, 30 Mar 2012 02:28:45 UTC +00:00], ["email", "test@test.com"], ["first_name", nil], ["last_name", nil], ["updated_at", Fri, 30 Mar 2012 02:28:45 UTC +00:00]]
(131.2ms) commit transaction
=> true
The ActiveRecord::Callbacks don’t support an
:onoption…From the Rails codebase, the only place that mentions handling an
:onoption is in the validations module code in ActiveModel::Validations.If you look through the ActiveRecord::Callbacks code, you’ll see that there’s no mention of
:on, nor does the ActiveRecord::Callbacks module include any of the ActiveModel::Validations module that will handle that option. There is an include for ActiveModel::Validations::Callbacks, but that will just provide the definitions for thebefore_andafter_validations methods. However, thebefore_validationandafter_validationcallbacks will handle the:onoption as seen here in their definitions.