Ryoichiro Kamiya
2009-Nov-08 08:04 UTC
Overriding initialize in active_record Model or after_initialize
Hi, I am trying to set initial process when instantiating model by overriding initialize() method which takes arguments. The initialize() method overrides the parent ActiveRecord::Base class''s by taking arguments and assign arguments to its instance variables. class Product < ActiveRecord::Base def initialize(item = nil) super # and then process to assign variables from item argument to instance variables # .... end In order to fully leverage ActiveRecord::Base class functionality, I''m calling super to run the default initialization process (i.e. set up all setter/getter methods). However, the Product class above still can''t find getter/setter methods for its variables. In the meantime, I found the following blog article suggesting use after_initialize instead of overriding Active Record object. Rails: Don''t override initialize on ActiveRecord objects http://blog.dalethatcher.com/2008/03/rails-dont-override-initialize-on.html I could not find ways to set arguments for this after_initialize approach. Can anybody advise should I override initialize() or use after_initialize with some ways to take arguments? Thanks, Ryo --~--~---------~--~----~------------~-------~--~----~ 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?hl=en -~----------~----~----~----~------~----~------~--~---
Frederick Cheung
2009-Nov-08 10:27 UTC
Re: Overriding initialize in active_record Model or after_initialize
On Nov 8, 8:04 am, Ryoichiro Kamiya <ryoichiro.kam...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > I am trying to set initial process when instantiating model by > overriding initialize() method which takes arguments. The initialize() > method overrides the parent ActiveRecord::Base class''s by taking > arguments and assign arguments to its instance variables. > > class Product < ActiveRecord::Base > > def initialize(item = nil) > super > # and then process to assign variables from item argument to > instance variables > # .... > endWhat does the actual code in there look like? What is the error that you get ? Fred> > In order to fully leverage ActiveRecord::Base class functionality, I''m > calling super to run the default initialization process (i.e. set up > all setter/getter methods). However, the Product class above still > can''t find getter/setter methods for its variables. In the meantime, I > found the following blog article suggesting use after_initialize > instead of overriding Active Record object. > > Rails: Don''t override initialize on ActiveRecord objectshttp://blog.dalethatcher.com/2008/03/rails-dont-override-initialize-o... > > I could not find ways to set arguments for this after_initialize > approach. > > Can anybody advise should I override initialize() or use > after_initialize with some ways to take arguments? > > Thanks, > Ryo
Ryo
2009-Nov-14 10:05 UTC
Re: Overriding initialize in active_record Model or after_initialize
Thanks Fred. I got the following error. NoMethodError in ProductsController#search undefined method `stringify_keys!'' for #<Amazon::Element:0x10373c6a8> /Library/User/Gems/1.8/gems/activerecord-2.3.3/lib/active_record/ base.rb:2731:in `attributes='' /Library/Ruby/Gems/1.8/gems/activerecord-2.3.3/lib/active_record/ base.rb:2434:in `initialize'' /Users/User/Documents/Aptana Studio Workspace/Flatworld/app/models/ product.rb:5:in `initialize'' /Users/User/Documents/Aptana Studio Workspace/Flatworld/app/models/ products.rb:31:in `new'' .... [more] and actual code for the model class is: ---------------------------------------------------------------- class Product < ActiveRecord::Base has_many :inventories def initialize(item) super @amazon_asin = item.get(''asin'') @manufacturer = item.get(''itemattributes/manufacturer'') @name = item.get(''itemattributes/title'') @releasedate = item.get(''itemattributes/releasedate'') @amazon_url = item.get(''detailpageurl'') @amazon_image = item.get_hash(''smallimage'') end ---------------------------------------------------------------- item is the result from Amazon API search result. I am trying to instantiate Product class with the result data set. Is this right approach to instantiate model class by overriding initialize method with super method within? Ryo On 11月8日, 午後6:27, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 8, 8:04 am, RyoichiroKamiya<ryoichiro.kam...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > Hi, > > > I am trying to set initial process when instantiating model by > > overriding initialize() method which takes arguments. The initialize() > > method overrides the parent ActiveRecord::Base class''s by taking > > arguments and assign arguments to its instance variables. > > > class Product < ActiveRecord::Base > > > def initialize(item = nil) > > super > > # and then process to assign variables from item argument to > > instance variables > > # .... > > end > > What does the actual code in there look like? What is the error that > you get ? > > Fred > > > > > In order to fully leverage ActiveRecord::Base class functionality, I''m > > calling super to run the default initialization process (i.e. set up > > all setter/getter methods). However, the Product class above still > > can''t find getter/setter methods for its variables. In the meantime, I > > found the following blog article suggesting use after_initialize > > instead of overriding Active Record object. > > > Rails: Don''t override initialize on ActiveRecord objectshttp://blog.dalethatcher.com/2008/03/rails-dont-override-initialize-o... > > > I could not find ways to set arguments for this after_initialize > > approach. > > > Can anybody advise should I override initialize() or use > > after_initialize with some ways to take arguments? > > > Thanks, > > Ryo
Frederick Cheung
2009-Nov-14 11:07 UTC
Re: Overriding initialize in active_record Model or after_initialize
On Nov 14, 10:05 am, Ryo <ryoichiro.kam...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> and actual code for the model class is: > ---------------------------------------------------------------- > class Product < ActiveRecord::Base > has_many :inventories > > def initialize(item) > super > @amazon_asin = item.get(''asin'') > @manufacturer = item.get(''itemattributes/manufacturer'') > @name = item.get(''itemattributes/title'') > @releasedate = item.get(''itemattributes/releasedate'') > @amazon_url = item.get(''detailpageurl'') > @amazon_image = item.get_hash(''smallimage'') > end > ---------------------------------------------------------------- > item is the result from Amazon API search result. I am trying toThe reason this isn''t working is that super does not mean ''call the superclass implementation with no arguments'' (which is fine in this case - Active Record just won''t set any attributes). It means ''call the super class implementation with the same arguments'', so you''re passing this an amazon search result object to a method expecting a hash. You can force the superclass to be called with no arguments by doing super(). I assume that you''re trying to set activerecord attributes for the title and so on. If so, use the accessor functions (ie self.amazon_asin = ... ). Active Record doesn''t store its attributes in instance variables, so what you''re doing won''t work. Lastly while you can make the above work, I think that you''ll be making life for yourself more difficult by requiring that Products be initialized with an amazon search result object (eg for creating objects in tests). another approach is to leave initialize alone and write class Product < ... def self.from_amazon_search_result(item) new :amazon_asin => item.get(''asin''), :manufacturer => item.get (''itemattributes/manufacturer'') , ... end end Fred
Ryo
2009-Nov-15 00:44 UTC
Re: Overriding initialize in active_record Model or after_initialize
It worked perfect as you suggested using class method "self.from_amazon_search_result". Does this mean I am instantiating Product object by this new class method rather than new()? Sorry this is new approach to me, and I just would like to know for my learning.> Active Record doesn''t store its attributes in instance variables, so what you''re doing won''t work.This was also new to me. I was building it on my belief that every instance of AR-extending class holds its attributes in instance variable. I will look for some specs on web just so I learn! Thanks again Fred! On 11月14日, 午後7:07, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Nov 14, 10:05 am, Ryo <ryoichiro.kam...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > and actual code for the model class is: > > ---------------------------------------------------------------- > > class Product < ActiveRecord::Base > > has_many :inventories > > > def initialize(item) > > super > > @amazon_asin = item.get(''asin'') > > @manufacturer = item.get(''itemattributes/manufacturer'') > > @name = item.get(''itemattributes/title'') > > @releasedate = item.get(''itemattributes/releasedate'') > > @amazon_url = item.get(''detailpageurl'') > > @amazon_image = item.get_hash(''smallimage'') > > end > > ---------------------------------------------------------------- > > item is the result from Amazon API search result. I am trying to > > The reason this isn''t working is that > > super > > does not mean ''call the superclass implementation with no > arguments'' (which is fine in this case - Active Record just won''t set > any attributes). It means ''call the super class implementation with > the same arguments'', so you''re passing this an amazon search result > object to a method expecting a hash. You can force the superclass to > be called with no arguments by doing super(). > > I assume that you''re trying to set activerecord attributes for the > title and so on. If so, use the accessor functions (ie > self.amazon_asin = ... ). Active Record doesn''t store its attributes > in instance variables, so what you''re doing won''t work. > > Lastly while you can make the above work, I think that you''ll be > making life for yourself more difficult by requiring that Products be > initialized with an amazon search result object (eg for creating > objects in tests). another approach is to leave initialize alone and > write > > class Product < ... > > def self.from_amazon_search_result(item) > new :amazon_asin => item.get(''asin''), :manufacturer => item.get > (''itemattributes/manufacturer'') , ... > end > end > > Fred