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 -~----------~----~----~----~------~----~------~--~---