I have a scenario where I need to dynamically create classes from existing application (external to app) databases, to pull data for reports. # Table definitions APP_TABLES = %w(#list of tables for a given app - I''m sure I could query this on a simple connect. But let''s stick to this for now.) APP_TABLES.each do |table_name| # camelize for class creation class_name = table_name.camelize klass = Class.new(App) # uses App class to establish_connection to externalDB klass = class_eval do #unsure about this. I need to set table_name to same as class name ActiveRecord::Base.set_table_name("#{class_name}") ActiveRecord::Base.const_set(constant_name, klass) end # class_eval # After creating the class - I want to establish an instance - but it says that the class does not exist - more specifically constant doesn''t exist. eval("#{table_name} = #{class_name}.new") I would love to hear thoughts on this, especially if I''m approaching this incorrectly. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 17, 10:02 am, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> klass = Class.new(App) # uses App class to establish_connection to > externalDB > > klass = class_eval do > #unsure about this. I need to set table_name to same as class name > ActiveRecord::Base.set_table_name("#{class_name}") > ActiveRecord::Base.const_set(constant_name, klass) > end # class_evalThis sounds fishy, you''re calling set_table_name on AR::Base, not your class. just klass.set_table_name ''blah'' should be enough> > # After creating the class - I want to establish an instance - but it > says that the class does not exist - more specifically constant doesn''t > exist. > eval("#{table_name} = #{class_name}.new") > > I would love to hear thoughts on this, especially if I''m approaching > this incorrectly. >You haven''t created a constant called class_name - ActiveRecord::Base.const_set(constant_name, klass) would have created ActiveRecord::Base::Foo. You probably wanted Object.const_set class_name, klass Fred> -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks for the reply. Frederick Cheung wrote in post #975422:>> klass = class_eval do >> #unsure about this. I need to set table_name to same as class name >> ActiveRecord::Base.set_table_name("#{class_name}") >> ActiveRecord::Base.const_set(constant_name, klass) >> end # class_eval > > This sounds fishy, you''re calling set_table_name on AR::Base, not your > class. just klass.set_table_name ''blah'' should be enoughTrue. I receive an unknown method error though.>> eval("#{table_name} = #{class_name}.new") > You haven''t created a constant called class_name - > You probably wanted Object.const_set class_name, klassSorry - I seem to have missed posting the class_name = table_name.camelize line in there (have large sections of comments that I didn''t want to clutter the post). I''ve changed the above code to: APP_TABLES.each do |table_name| class_name = table_name.camelize klass = Class.new(App) constant_name = "#{class_name}" klass = class_eval do set_table_name("#{class_name}") or puts "Class set table name failed" Object.const_set(constant_name, klass) or puts "Class name constant set failed" end # class_eval but get an unknown method error on the set_table_name call. The App class (below) inherits from ActiveRecord::Base which in turn should have that method. class App < ActiveRecord::Base abstract_class = true def initialize establish_connection :app_development end # to avoid trying to connect to the Spydirdb table by default def self.columns() @columns ||= []; end 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 17, 12:44 pm, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> > klass = class_eval do > set_table_name("#{class_name}") or puts "Class set table name > failed" > Object.const_set(constant_name, klass) or puts "Class name > constant set failed" > end # class_eval > > but get an unknown method error on the set_table_name call.you don''t need the class_eval . just klass.set_table_name should work (I don''t think the method is protected, if it is you might have to use send)> > The App class (below) inherits from ActiveRecord::Base which in turn > should have that method. > > class App < ActiveRecord::Base > abstract_class = true >this should be self.abstract_class = true (right now you''re just setting a local variable)> def initialize > establish_connection :app_development > end >This is dodgy. First of all you''re overriding initialize, but without calling through to the super class, so your activerecord objects won''t get initialized properly. You''ve also change the signature of initialize. Also, do you really want to be reconnecting to the database everytime a new instance is created? lastly this establish_connection is a class method> # to avoid trying to connect to the Spydirdb table by default > def self.columns() @columns ||= []; end > end > > -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung wrote in post #975445:> On Jan 17, 12:44pm, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote: >> class App < ActiveRecord::Base >> abstract_class = true >> > this should be self.abstract_class = true (right now you''re just > setting a local variable)Point taken.>> def initialize >> establish_connection :app_development >> end >> > This is dodgy. First of all you''re overriding initialize, but without > calling through to the super class, so your activerecord objects won''t > get initialized properly.Taken from online suggestions for handling multiple DBs.> You''ve also change the signature of > initialize. Also, do you really want to be reconnecting to the > database everytime a new instance is created? lastly this > establish_connection is a class methodThanks. I''ll fix all that and get back to you. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
# APP_TABLES contain a list of table names - would be better to dynamically read them after connecting APP_TABLES.each do |table_name| class_name = table_name.camelize klass = Class.new(App) constant_name = "#{class_name}" # even though klass is created with App as superclass (inheriting from ActiveRecord::Base, the set_table_name seems to be unavailable - what am I missing here? klass.set_table_name ("#{class_name}") or puts "Class set table name failed" klass.const_set(constant_name, klass) or puts "Class name constant set failed" eval("#{table_name} = #{class_name}.new") or puts "Class instantiation failed" end How can I determine if the klass has actually been created? How long will the dynamic classes exist in memory? For the duration of this rake task execution? Is there a way to list classes created at runtime? -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 18, 6:31 am, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> # APP_TABLES contain a list of table names - would be better to > dynamically read them after connecting > > APP_TABLES.each do |table_name| > class_name = table_name.camelize > klass = Class.new(App) > constant_name = "#{class_name}" > > # even though klass is created with App as superclass (inheriting from > ActiveRecord::Base, the set_table_name seems to be unavailable - what am > I missing here?what happens when you try?> klass.set_table_name ("#{class_name}") or puts "Class set table name > failed" > klass.const_set(constant_name, klass) or puts "Class name constant set > failed" > eval("#{table_name} = #{class_name}.new") or puts "Class instantiation > failed" > end > > How can I determine if the klass has actually been created?I don''t think Class.new can actually fail> How long will the dynamic classes exist in memory?> For the duration of this rake task execution? > Is there a way to list classes created at runtime?I think that klass exists much like any variable - it may be garbage collected if nothing references it (classes might be special though) . You can step through objects of any class (including Class) via objectspace, although you probably won''t be able to distinguish classes created like this from other classes. Fred> > -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Thanks for your repeated answers. Frederick Cheung wrote in post #975619:> what happens when you try?Class set table name failed -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 18, 7:55 am, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> Thanks for your repeated answers. > > Frederick Cheung wrote in post #975619: > > > what happens when you try? > > Class set table name failed >That''s just what you''re printing out - the return value of set_table_name isn''t documented, so i wouldn''t assume nil or false to mean failure Fred> -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung wrote in post #975672:> That''s just what you''re printing out - the return value of > set_table_name isn''t documented, so i wouldn''t assume nil or false to > mean failureOK, so I''m down to: class ExternalApp < ActiveRecord::Base self.abstract_class = true establish_connection :external_app def self.columns() @columns ||= []; end end #App tables has a list of tables in external app, until I get this bit working APP_TABLES.each do |table_name| constant_name = class_name = table_name.camelize klass = Class.new(ExternalApp) klass.set_table_name ("#{class_name}") klass.const_set(constant_name, klass) eval("#{table_name} = #{class_name}.new") or puts "Class instantiation failed" end On running this rake task I get the following error: lib/rspec/core/backward_compatibility.rb:20:in `const_missing'': uninitialized constant Services Is const_set where the klass name is ''set in stone''? -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On 19 Jan 2011, at 08:05, Sem Ptiri <lists-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> #App tables has a list of tables in external app, until I get this bit > working > APP_TABLES.each do |table_name| > constant_name = class_name = table_name.camelize > klass = Class.new(ExternalApp) > klass.set_table_name ("#{class_name}") > klass.const_set(constant_name, klass) > eval("#{table_name} = #{class_name}.new") or puts "Class instantiation > failed" > end > > > On running this rake task I get the following error: > > lib/rspec/core/backward_compatibility.rb:20:in `const_missing'': > uninitialized constant Services > > Is const_set where the klass name is ''set in stone''?It is, but you''re using it back to front: klass.const_set sets a constant on klass, whereas you want to set a top level constant ie Object.const_set Fred.> > -- > 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en. >-- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung wrote in post #975964:> It is, but you''re using it back to front: klass.const_set sets a > constant on klass, whereas you want to set a top level constant ie > Object.const_setThat makes sense, thought it might be a scope problem. Thank you. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Ok, so this seems to work 1) Create dynamic classes from a list (some rework on getting that from tables automatically needed) 2) Instantiate those objects A minor error pops up now. The tables exist, as do the fields. However, with: service = Services.new(:portID => 333, :method => "PUT") But I get the error: unknown attribute: portID -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung wrote in post #975964:> It is, but you''re using it back to front: klass.const_set sets a > constant on klass, whereas you want to set a top level constant ie > Object.const_setYou are my personal hero, today. Thank you so much for helping out on this thread. It works. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Jan 19, 8:35 am, Sem Ptiri <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> The tables exist, as do the fields. > > However, with: > > service = Services.new(:portID => 333, :method => "PUT") > > But I get the error: > > unknown attribute: portID >Probably the result of you suppressing the columns method. If AR things there are no columns, it will think there are no attributes Fred> -- > Posted viahttp://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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung wrote in post #975987:> Probably the result of you suppressing the columns method. If AR > things there are no columns, it will think there are no attributesFrom the superclass. Right. Thanks. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Everything''s perfect now. Thanks again for the repeated replies. -- 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.