Forum: Ruby on Rails Extending a class from plugin, need always restart server?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cameron B. (Guest)
on 2007-02-01 00:20
Hi there,

So, I've got a class from a plugin installed in /vendor/plugins. I want
to change it a bit, customizing how it works, so I've created a file
(/lib/myextension.rb):

<pre>
class TheClass
 def somestuff
end
end
</pre>

Then, I required the file from my environment.rb:

<pre>
require 'lib/myextension'
</pre>

Here's my question. Every time I change my class extension, I get
errors...seems like I need to restart my web server (or script/console)
with every change, which is making development very slow.

In script/console I've tried "reload!", and it doesn't seem to help. I
put "include Reloadable" into the class and that doesn't seem to help
either.

Am I missing something??

Thanks in advance!!

Cameron

pw. The error I get after making a change is:

<pre>
undefined method `somestuff' for Comatose::Page:Class
</pre>
Stephan W. (Guest)
on 2007-02-01 10:04
Cameron B. wrote:
> Hi there,
>
> So, I've got a class from a plugin installed in /vendor/plugins. I want
> to change it a bit, customizing how it works, so I've created a file
> (/lib/myextension.rb):
>
> <pre>
> class TheClass
>  def somestuff
> end
> end
> </pre>
>
> Then, I required the file from my environment.rb:
>
> <pre>
> require 'lib/myextension'
> </pre>
>
> Here's my question. Every time I change my class extension, I get
> errors...seems like I need to restart my web server (or script/console)
> with every change, which is making development very slow.
>
> In script/console I've tried "reload!", and it doesn't seem to help. I
> put "include Reloadable" into the class and that doesn't seem to help
> either.
>
> Am I missing something??

Well, maybe you can put the code that you are developing closer to were
you can see how it works during development, e.g. a controller, or
model, and then move it out into the lib directory once you are
satisfied with its functionality.

Or, you could develop it against a unit test. When running tests your
lib entries are reloaded. And you'd have a nice way to see that your
changes are still good once the next release of Comatose comes along.

Stephan

> Thanks in advance!!
>
> Cameron
>
> pw. The error I get after making a change is:
>
> <pre>
> undefined method `somestuff' for Comatose::Page:Class
> </pre>
Cameron B. (Guest)
on 2007-02-01 20:43
Stephan W. wrote:

> Well, maybe you can put the code that you are developing closer to were
> you can see how it works during development, e.g. a controller, or
> model, and then move it out into the lib directory once you are
> satisfied with its functionality.
>
> Or, you could develop it against a unit test. When running tests your
> lib entries are reloaded. And you'd have a nice way to see that your
> changes are still good once the next release of Comatose comes along.

Hi Stephan,

So my attempt at generalization has given me away as extending comatose.
;-) No worries there, Comatose is great!!

Thanks for the suggestions. The unit testing idea makes sense to me for
sure, and is a good suggestion.

As for straight development (not in /test), since I'm extending the
comatose page class, and view controller, I'm using the /lib dir because
I don't really know where else I should put stuff like this. Would it
make sense to put this stuff in app/models and app/controllers even
though they aren't full-on models/controllers, but just opening up a
model/controller class and adding methods?

Does rails reload everything in the app/models and app/controllers
folders on each load, but not the /lib stuff?

Thanks!
Rick O. (Guest)
on 2007-02-01 21:26
(Received via mailing list)
On 2/1/07, Cameron B. <removed_email_address@domain.invalid> wrote:
> > changes are still good once the next release of Comatose comes along.
> comatose page class, and view controller, I'm using the /lib dir because
> I don't really know where else I should put stuff like this. Would it
> make sense to put this stuff in app/models and app/controllers even
> though they aren't full-on models/controllers, but just opening up a
> model/controller class and adding methods?
>
> Does rails reload everything in the app/models and app/controllers
> folders on each load, but not the /lib stuff?
>
> Thanks!

Rails reloads everything in /lib too if it was autoloaded.

Be careful about extending your rails app classes from plugins.
Remember that the load cycle goes like this: Rails => Plugins => App.
Plugins can safely monkey patch Rails, since neither are reloaded.
However, modifying your app classes can be troublesome.  What if
Plugin A includes itself into Post, yet Post has code that depends on
Plugin A and B?  You get an error, that's what.

2 suggestions:

1) It's okay to require users to add code to their app to load
plugins.  Requiring a manual "include FooMethods" is fine.  It makes
it more explicit that you're using a plugin.  Common acts_as_* plugins
will define a single class method on ActiveRecord::Base that does
little more than setting some options and including some modules.

2) I wrote a little "include_into" hack to Module.
http://weblog.techno-weenie.net/2006/11/15/extendi...

I'd advise #1 unless you're pretty familiar with ruby/rails.


--
Rick O.
http://weblog.techno-weenie.net
http://mephistoblog.com
Stephan W. (Guest)
on 2007-02-01 21:38

 Cameron B. wrote:
> Stephan W. wrote:
>
>> Well, maybe you can put the code that you are developing closer to were
>> you can see how it works during development, e.g. a controller, or
>> model, and then move it out into the lib directory once you are
>> satisfied with its functionality.
>>
>> Or, you could develop it against a unit test. When running tests your
>> lib entries are reloaded. And you'd have a nice way to see that your
>> changes are still good once the next release of Comatose comes along.
>
> Hi Stephan,
>
> So my attempt at generalization has given me away as extending comatose.
> ;-) No worries there, Comatose is great!!
>
> Thanks for the suggestions. The unit testing idea makes sense to me for
> sure, and is a good suggestion.
>
> As for straight development (not in /test), since I'm extending the
> comatose page class, and view controller, I'm using the /lib dir because
> I don't really know where else I should put stuff like this. Would it
> make sense to put this stuff in app/models and app/controllers even
> though they aren't full-on models/controllers, but just opening up a
> model/controller class and adding methods?

/vendor is for non-app specific code from others -- /lib for your
non-app specific code.

I don't know what you're doing, but my (first) suggestion was you could
put the code you are developing straight into any model/controller
you're working with, as long as you know how to extract it into the lib
directory when you're done.

If Rick Olsen's recommendation works out for you, maybe you don't need
to go through this, and you should first properly hook up the changes
you're applying to Comatose. ("Don't know what you're doing.")


See you

Stephan



> Does rails reload everything in the app/models and app/controllers
> folders on each load, but not the /lib stuff?
>
> Thanks!
Cameron B. (Guest)
on 2007-02-01 23:14
Stephan W. wrote:

> /vendor is for non-app specific code from others -- /lib for your
> non-app specific code.
>
> I don't know what you're doing, but my (first) suggestion was you could
> put the code you are developing straight into any model/controller
> you're working with, as long as you know how to extract it into the lib
> directory when you're done.
>
> If Rick Olsen's recommendation works out for you, maybe you don't need
> to go through this, and you should first properly hook up the changes
> you're applying to Comatose. ("Don't know what you're doing.")
>

Thanks for the suggestions Rick, and Stephan. I'm not trying to be
secretive about what I'm doing, just thought being generic would make it
applicable to a wider audience...guess it's obfuscating the issue.

Basically I have the Comatose plugin, and I want to adjust how the
Comatose::Page model, and the ComatoseController controller work a bit,
but I don't want to edit those files directly (breaking future upgrade
paths).

My thinking was to create my own app-specific overrides in the /lib
folder, where for each case I just open up the class, fiddle with it how
I need, and that's it, eg:

# lib/comatose_page_overrides.rb
#
# This is intended to override/extend:
# vendor/plugins/comatose/lib/comatose/page.rb
class Comatose::Page
  def some_new_method
    # do my new stuff
  end

  def some_existing_method
    # override how plugin works by default
  end
end

My overrides are working how I want, it's just the need to restart the
server with each change I make to the file. The difficulty I'm having is
somehow related to the fact that rails plugins aren't reloaded
automatically on each call,  yet I want my overrides to be reloaded
automatically.

I'll look into the stuff you both mention though and see if I can figure
it out ;-)

Cameron
This topic is locked and can not be replied to.