# Why doesn't AR find method cause a call to obj.initialize?

**URL:** <https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157>\
**Category:** Rails\
**Created:** [September 19, 2006, 1:49am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157 "2006-09-19T01:49:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 1:49am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/1 "2006-09-19T01:49:41Z")

</div>

All,

I have a method that does a find on an object by id, like so:

contact = Contact.find(3)

A contact has a contact\_preference, like so:

has\_one :contact\_preference, :foreign\_key =\> :ContactNumber,  
:dependent =\> true

In my Contact object, I’ve created an initialize method:

def initialize(attributes = nil)  
super(attributes)  
self.create\_contact\_preference unless self.contact\_preference  
end

The purpose of this initialize method is to add a contact\_preference  
member to the contact if they don’t have one already in the database  
(which none of the legacy records do).

However, it is clear that my initialize method is not being called due  
to the find() invocation.

Does find() call a different constructor on an AR object? If so, which  
one?

Am I creating my contact\_preference member incorrectly?

Thanks,  
Wes

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 2:29am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/2 "2006-09-19T02:29:51Z")

</div>

Well, I think I’ve verified the behavior that I’m seeing based on the  
code below and the use of allocate, instead of new. As we can see,  
find() does not call initialize at all.

What I was hoping to be able to do here was to have the Contact object  
be smart enough to generate it’s contact\_preference member when  
necessary. I don’t think that this is an unreasonable expectation for  
an object.

I guess I’ve been thinking of Ruby’s new method as the equivalent to new  
in Java, but in fact, Ruby’s allocate is equivalent to Java’s new.  
This is slightly confusing.

Does anyone know why AR::Base uses allocate instead of new? I’m sure  
that there’s a good reason.

I see that there is an “after\_find()” callback available to me. Is this  
what I need?

Thanks,  
Wes

=================================================================

def instantiate(record)  
object =  
if subclass\_name = record[inheritance\_column]  
if subclass\_name.empty?  
allocate  
else  
require\_association\_class(subclass\_name)  
begin  
compute\_type(subclass\_name).allocate  
rescue NameError  
raise SubclassNotFound,  
"The single-table inheritance mechanism failed to locate the  
subclass: ‘#{record[inheritance\_column]}’. " +  
"This error is raised because the column  
‘#{inheritance\_column}’ is reserved for storing the class in case of  
inheritance. " +  
"Please rename this column if you didn’t intend it to be  
used for storing the inheritance class " +  
“or overwrite #{self.to\_s}.inheritance\_column to use another  
column for that information.”  
end  
end  
else  
allocate  
end

object.instance\_variable\_set("@attributes", record)  
object  
end

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 2:47am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/3 "2006-09-19T02:47:27Z")

</div>

initialize is called with Contact.new, Contact.find constructs object  
using  
Contact.instantiate. You can probably do this:

class Contact  
class \<\< self  
def instantiate\_with\_contact\_preference(record)  
object = instantiate\_without\_contact\_preference(record)  
# Do whatever you want with the object here  
object  
end

```
alias_method_chain :instantiate, :contact_preference

```

end  
end

-Jonathan

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 2:51am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/4 "2006-09-19T02:51:51Z")

</div>

after\_find is what I needed.

I’m still kind of annoyed at the difference in behavior.

I’m trying to figure out why finders couldn’t/shouldn’t call initialize  
methods.

What’s the difference in me applying my object customizations to my  
object in after\_find vs. initialize?

If the finders called initialize, then the instantiation model for  
AR::Base descendants would be consistent.

As it stands now, I have AR::Base descendants that do “create from  
scratch” initialization in the initialize method and other AR::Base  
descendants that do “create from persisted DB data” initialization in  
the “after\_find” method.

For someone new to Ruby as I am, who is already comfortable with OO,  
it’s weird to have to do object initialization a special way just for  
retrieved DB objects.

Wes

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 9:09am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/5 "2006-09-19T09:09:42Z")

</div>

Just a guess here. When you find() a record, you aren’t creating a  
brand new object, but are reconstructing an old object from a persistent  
representation of it stored in the database. So AR::initialize isn’t  
useful since it can’t tell whether it would be for a new object or a  
reconstructed one. Therefore you use after\_initialize or after\_find to  
init the required attributes.

Or maybe it’s something else. Like I said, I’m just guessing.

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

Wes G. wrote:

> This is a valid solution - thanks for it.
> 
> However, it begs the question - why the difference in object  
> instantiation?

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 6:03pm UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/6 "2006-09-19T18:03:05Z")

</div>

Josh S. wrote:

> Just a guess here. When you find() a record, you aren’t creating a  
> brand new object, but are reconstructing an old object from a persistent  
> representation of it stored in the database. So AR::initialize isn’t  
> useful since it can’t tell whether it would be for a new object or a  
> reconstructed one. Therefore you use after\_initialize or after\_find to  
> init the required attributes.

Yes, but in reality, I am creating a new object in memory regardless of  
whether I do it directly with new() or indirectly with find(). I should  
be able to have an initialization hook that is consistent regardless of  
instantiation method. If I’m doing stuff to my AR::Base descendant that  
doesn’t even have anything to do with the database, than why can’t that  
work be done the same way regardless of how the object is created?

Clearly the hooks are there, I’m just wondering why/complaining that  
they aren’t the same. Just another detail that I have to master, and I  
wanna know why :).

Wes

---

<div class="post-metadata">

**Author:** ![weyus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/7ab992/32.png) [@weyus](https://www.ruby-forum.com/u/weyus)\
**Post date:** [September 19, 2006, 2:55am UTC](https://www.ruby-forum.com/t/why-doesnt-ar-find-method-cause-a-call-to-obj-initialize/69157/7 "2006-09-19T02:55:37Z")

</div>

Jonathan,

This is a valid solution - thanks for it.

However, it begs the question - why the difference in object  
instantiation?

Wes
