# Having trouble extending a class from a Rails plugin

**URL:** <https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077>\
**Category:** Rails\
**Created:** [April 8, 2009, 10:27pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077 "2009-04-08T22:27:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [April 8, 2009, 10:27pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077/1 "2009-04-08T22:27:05Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [April 8, 2009, 11:25pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077/2 "2009-04-08T23:25:50Z")

</div>

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/](http://alinhavado.wordpress.com/) (pt-br) | [http://blog.codevader.com/](http://blog.codevader.com/)  
(en)

On Wed, Apr 8, 2009 at 5:27 PM, Jason F.

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [April 8, 2009, 11:40pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077/3 "2009-04-08T23:40:39Z")

</div>

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\_method  
> > NoMethodError: undefined method `a\_method’ for  
> > #Jason::MyClass:0x408b444

> Jason::MyClass.class\_eval do  
> def another\_method  
> # do whatever you want to do here.  
> end  
> end

I 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

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [April 8, 2009, 11:49pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077/4 "2009-04-08T23:49:19Z")

</div>

On Wed, Apr 8, 2009 at 6:40 PM, Jason F.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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/](http://alinhavado.wordpress.com/) (pt-br) | [http://blog.codevader.com/](http://blog.codevader.com/)  
(en)

---

<div class="post-metadata">

**Author:** ![jfoxny](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/a6a055/32.png) [@jfoxny](https://www.ruby-forum.com/u/jfoxny)\
**Post date:** [April 9, 2009, 4:28pm UTC](https://www.ruby-forum.com/t/having-trouble-extending-a-class-from-a-rails-plugin/165077/5 "2009-04-09T16:28:47Z")

</div>

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
