I have class in a plugin that I want to crack open and add some functionality to for a particular application. So, I created a file by the same name as the class in my app/models folder and added some methods to the class, but, I can''t seem to get Rails (2.2.2) to pick-up the extended definition. I did find while trying to debug the problem that if I paste the extended definition into, say, environment.rb it works fine. Also, if I require_dependency "#{RAILS_ROOT}/app/models/my_class.rb" in the plugin''s version of the class it also works fine (obviously not desirable). All of this leads me to believe that my problem has something to do with the class loader, but, I can''t figure it out. I''ve laid out an example below that illustrates my problem. Any help would be much appreciated. Thanks, Jason # vendor/plugins/my_plugin/init.rb require ''my_plugin'' # vendor/plugins/my_plugin/lib/my_plugin.rb module Jason class MyClass def a_method # ... end end end # app/models/my_class.rb module Jason class MyClass def another_method # ... end end end $ script/console>> Jason::MyClass.new.another_methodNoMethodError: undefined method `another_method'' for #<Jason::MyClass:0x408b444> -- 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?hl=en -~----------~----~----~----~------~----~------~--~---
Maurício Linhares
2009-Apr-08 21:25 UTC
Re: Having trouble extending a class from a Rails plugin
Unfortunately it will never work the way you want it to. Place this code into an initializer file (under the initializers folder) or place it under the "lib" folder and do an explicit require. Also, if all you want to do is to add a method to a class defined elsewhere, do it like this: Jason::MyClass.class_eval do def another_method # do whatever you want to do here. end end - Maurício Linhares http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/ (en) On Wed, Apr 8, 2009 at 5:27 PM, Jason Fox <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > I have class in a plugin that I want to crack open and add some > functionality to for a particular application. So, I created a file by > the same name as the class in my app/models folder and added some > methods to the class, but, I can''t seem to get Rails (2.2.2) to pick-up > the extended definition. > > I did find while trying to debug the problem that if I paste the > extended definition into, say, environment.rb it works fine. Also, if I > require_dependency "#{RAILS_ROOT}/app/models/my_class.rb" in the > plugin''s version of the class it also works fine (obviously not > desirable). > > All of this leads me to believe that my problem has something to do with > the class loader, but, I can''t figure it out. I''ve laid out an example > below that illustrates my problem. Any help would be much appreciated. > > Thanks, > Jason > > > # vendor/plugins/my_plugin/init.rb > require ''my_plugin'' > > # vendor/plugins/my_plugin/lib/my_plugin.rb > module Jason > class MyClass > def a_method > # ... > end > end > end > > # app/models/my_class.rb > module Jason > class MyClass > def another_method > # ... > end > end > end > > $ script/console >>> Jason::MyClass.new.another_method > NoMethodError: undefined method `another_method'' for > #<Jason::MyClass:0x408b444> > -- > 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks for the reply, Maurício. Out of curiosity, what is the reason that this does not work the way that I thought it would. I am planning to delve into the Rails class loader code tonight, but, if you can shed any light on this I''d much appreciated it.> Place this code into an initializer file (under the initializers > folder) or place it under the "lib" folder and do an explicit require.I''ve actually had similar problems trying to use initializers with plugins in the past. Specifically, I''ve tried to use an initializer to define application specific values for constants used by my plugin. For example: # config/initializers/my_class.rb class Jason::MyClass MY_CONSTANT = "the application''s value for this constant" end Rails, in this case, appears to load the class definition from the initializer and stops there, i.e., it never loads the rest of the class definition from the plugin. So, calling a method defined in the plugin''s version of the class like a_method, would also result in the NoMethodError... $ script/console>> Jason::MyClass.new.a_methodNoMethodError: undefined method `a_method'' for #<Jason::MyClass:0x408b444>> Jason::MyClass.class_eval do > def another_method > # do whatever you want to do here. > end > endI actually tried this approach. I placed this exact code in my app/models/my_class.rb version of the class and it results in the same NoMethodError. However, if I place it in environment.rb it works like a charm! :-/ It seems to me that once the class has been defined either by the plugin or by an initializer (it appears the initializer is loaded, then the plugin, then the model), Rails will not allow any modifications to it. Any additional thoughts? Jason -- 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Maurício Linhares
2009-Apr-08 21:48 UTC
Re: Having trouble extending a class from a Rails plugin
On Wed, Apr 8, 2009 at 6:40 PM, Jason Fox <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> It seems to me that once the class has been defined either by the plugin > or by an initializer (it appears the initializer is loaded, then the > plugin, then the model), Rails will not allow any modifications to it. > Any additional thoughts?You just figured out the problem by yourself :) If the class is already loaded, Rails will not try to load it again, no matter what you do, that''s why I showed you the class_eval approach. Using class_eval (instead of directly "defining" a class) will make Rails try to load the class from somewhere else (that would be your plugin) and you woudn''t have any method missing or class not being loaded issues. Once again, place that code into an initializer and you''re done, but placing it under app/models won''t work. - Maurício Linhares http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/ (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-/JYPxA39Uh5TLH3MbocFFw@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 -~----------~----~----~----~------~----~------~--~---
Maurício Linhares wrote: Thanks again for the reply Maurício.> You just figured out the problem by yourself :)I''m curious as to why it works if I paste the extended class definition into environment.rb. I also found that if I include the following at the end of my environment.rb it works as I thought it might. Do you know why this is an exception to the rule? # config/environment.rb require ''jason/my_class''> If the class is already loaded, Rails will not try to load it again, > no matter what you do, that''s why I showed you the class_eval > approach. Using class_eval (instead of directly "defining" a class) > will make Rails try to load the class from somewhere else (that would > be your plugin) and you woudn''t have any method missing or class not > being loaded issues.I did try the class_eval approach, however, based on your comment, I was putting the code in the wrong spot. I had placed the code into the app/models/my_class.rb. I guess it needs to go into an initializer. Do you know why that is? Thanks again for the reply! Jason -- 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Reasonably Related Threads
- Rails 3.o
- passing model data to a plugin called within that model
- [LLVMdev] [cfe-dev] draft rule for naming types/functions/variables
- [LLVMdev] [cfe-dev] draft rule for naming types/functions/variables
- How Can I insert another column data into the CSV file when I use FasterCSV?