I noticed that Rails doesn't trigger after_initialize
callback when the callback symbol is passed as input.
The code below doesn't work.
class User < ActiveRecord::Base
after_initialize :init_data
def init_data
puts "In init_data"
end
end
The code below works.
class User < ActiveRecord::Base
def after_initialize
init_data
end
def init_data
puts "In init_data"
end
end
Can somebody explain this behavior?
Note 1
The ActiveRecord documentation says the following about after_initialize
:
Unlike all the other callbacks, after_find and after_initialize will
only be run if an explicit implementation is defined (def after_find).
In that case, all of the callback types will be called.
Though it is stated that after_initialize requires explicit implementation, I find the second sentence in the above paragraph ambiguous, i.e. In that case, all of
the callback types will be called.
What is all of the call back types
?
The code sample in the documentation has an ex开发者_运维百科ample that doesn't use explicit implementation:
after_initialize EncryptionWrapper.new
According to the documentation, you cannot use the macro-style class methods for the after_initialize
or after_find
callbacks:
The after_initialize and after_find callbacks are a bit different from the others. They have no before_* counterparts, and the only way to register them is by defining them as regular methods. If you try to register after_initialize or after_find using macro-style class methods, they will just be ignored. This behaviour is due to performance reasons, since after_initialize and after_find will both be called for each record found in the database, significantly slowing down the queries.
In short, you have to define an after_initialize
instance method:
class User < ActiveRecord::Base
def after_initialize
do_stuff
end
end
I'm pretty sure that methods invoked by symbol need to be protected or private.
Edit: Yep, here's the Rails 3 documentation:
The method reference callbacks work by specifying a protected or private method available in the object
精彩评论