ActiveRecord::Base doesn't always use
new
to create objects, so
initialize
might not be called.
I wanted to use a Hash on an
ActiveRecord::Base
subclass to store some calculated values, so I naively did this:
class User < ActiveRecord::Base
def initialize(args = nil)
super
@my_cache = {}
end
end
However I quickly ran into some "
You have a nil object when you didn't expect it!
" issues. Some debugger investigation revealed that the
@my_cache
variable wasn't being set when I called
find_or_create_
if the object already existed in the database.
Digging in the source revealed that the
instantiate
method in active_record/base.rb uses
allocate
to create classes rather than
new
. This means the
initialize
method is being neatly sidestepped when creating objects from the database.
The solution is to use the '
after_initialize
' callback:
class User < ActiveRecord::Base
def after_initialize
@my_cache = {}
end
end
One further note of caution, When passing parameters into a
new
or
create
method the
after_initialize
is called after the parameters have been set. So you can't rely on the initialization being done before overridden accessors are called.