I just found out the hard way that after_initialize is called after both
a “new” call on an AR object as well as a “find” call. So I’d like to
summarize my understanding of these and have someone tell me if I’m
correct.
Given an AR descendant “X”
after_create: Gets called only after X.new
after_initialize: Gets called after either X.new and X.find
after_find: Gets called only after X.find
Is this correct?
Does after_initialize only exist so that you don’t have to specify
the same method in two callbacks (after_create and after_find)?
FYI, after_create behavior can also be achieved by directly overriding
the initialize method in your AR object.
I find the name “after_initialize” confusing, but that’s another story
…
after_create is called after a call to X.create. That makes sense.
after_initialize is called after both X.new and X.find. The fact that
it’s called after find is totally annoying since I may just want to do object initialization for X.
It would seem that to do object initialization that only gets called as
part of a call to X.new, you have two choices:
Override the AR initialize(attributes = nil) method with your own and
do you initialization there.
(NOTE: For people who have been doing OO for a long time, this can be
somewhat confusing since one would think that initialize would also be
called after X.find - but of course, it isn’t. ActiveRecord manages
it’s initialization in a custom way).
Implement after_initialize and wrap all of your data initialization
in a if self.new_record? block. While this is less intuitive to
long-time OOers, it does respect the AR API more and isn’t bound to the
current implementation of the initialize method in AR::Base.
#2 is more API respectful, but #1 will perform better and feels more
natural.