Wes Gamble
2006-Sep-18 23:49 UTC
Why doesn''t AR find method cause a call to obj.initialize?
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
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Wes Gamble
2006-Sep-19 00:29 UTC
Re: Why doesn''t AR find method cause a call to obj.initializ
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
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Jonathan Viney
2006-Sep-19 00:43 UTC
Re: Why doesn''t AR find method cause a call to obj.initialize?
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
On 9/19/06, Wes Gamble
<rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>
wrote:>
>
> 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
>
> --
> Posted via http://www.ruby-forum.com/.
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Wes Gamble
2006-Sep-19 00:51 UTC
Re: Why doesn''t AR find method cause a call to obj.initializ
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 -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Wes Gamble
2006-Sep-19 00:55 UTC
Re: Why doesn''t AR find method cause a call to obj.initializ
Jonathan, This is a valid solution - thanks for it. However, it begs the question - why the difference in object instantiation? Wes -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Josh Susser
2006-Sep-19 07:09 UTC
Re: Why doesn''t AR find method cause a call to obj.initializ
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 Susser http://blog.hasmanythrough.com Wes Gamble wrote:> This is a valid solution - thanks for it. > > However, it begs the question - why the difference in object > instantiation?-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Wes Gamble
2006-Sep-19 16:03 UTC
Re: Why doesn''t AR find method cause a call to obj.initializ
Josh Susser 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 -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---