NetManiac

Witold Rugowski on web20 wave with Ruby on Rails

Reloading Your plugin in development mode

Posted on January 7, 2009 - Filed Under RubyOnRails

If you're new here, you may want to subscribe to my RSS feed. You can also get updates by email Thanks for visiting!

For one of my customers I was developing API, wrapped around some older service. This API was meant to be used by new application developed (using RoR of course) by customer itself. Since I was only wrapping old code I could finish quite soon, before main application was ready.

The problem was that API was not defined in every detail upfront. Since I did plain wrapping I did keep old business logic and flow with this API, and new application was not thinking the same way. This was seen before so we have agreed that integration will be done by me and we needed simple way to hook into new application with my integration code. One of obvious ways to achieve it is to use Rails plugin to keep code separated.

Things went OK but I want to share one thing I have learned. Using Rails plugin to wrap code is good idea with one issue – code reloading. Plugin code is not reloaded in development mode (like it is done with controllers or models) so changes in plugin will be visible after application restart. Not very comfortable for development…

Tools for developer

(c) batega

Being lazy and didn’t want to restart application with every change I make, I have started search for some workaround:

In module Dependencies (ActiveSupport::Dependencies in Rails 2.2, Dependencies in main namespace in Rails 2.1 and before) is a little, undocumented attribute explicitly_unloadable_constants, holding array of constants names which will be reloaded with each Rails request. So we just need to add our plugin module name to this array. In config/environments/development.rb add:

ActiveSupport::Dependencies.explicitly_unloadable_constants << 'MyPlugin'

But with plugin You must allow for that. Rails keeps list of paths where reloading is forbidden by default - it is Dependencies.load_paths_once. All plugin directories are on this list. So get rid of this (code for Rails 2.2 - Dependencies scoping):

["my_plugin"].each do |plugin_name|
  reloadable_path = RAILS_ROOT + "/vendor/plugins/#{plugin_name}/lib"
  ActiveSupport::Dependencies.load_once_paths.delete(reloadable_path)
end

Now with each request your plugin will be reloaded (but keep in mind that if you are requiring other files from this plugin, they may not be reloaded - require does keep own list of already loaded paths)

To be honest, this method I have learned from post on Bill Harding's blog, earlier I was just using Dependencies.load_file(and plugin directory removal from load_once_paths) to force reload my plugin:

before_filter :force_plugin_reload
def force_plugin_reload
   ActiveSupport::Dependencies.load_file "my_plugin.rb" if "development" == RAILS_ENV
end

Apparently explicitly_unloadable_constants is much more elegant solution. When do You want to reload something in lib directory You don't have to remove anything from load_once_paths - just add Your module name to .explicitly_unloadable_constants.

Maybe You will find this useful - or do You have other ways how to reload plugins in development mode?

Popularity: 22% [?]

Hits for this post: 45638

Similar Posts

Comments

8 Responses to “Reloading Your plugin in development mode”

  1. Michael Franzl on February 27th, 2009 13:59

    Thank you for this great post, you saved me a lot of time!

  2. Misuse » Reloading Classes in Rails on May 9th, 2009 6:08

    Kramer auto Pingback[...] Reloading plug-ins in development mode [...]

  3. How do I make the code in lib/ automatically reload when the file changes? - Stack Overflow on May 20th, 2009 18:58

    Kramer auto Pingback[...] a link to the article. I got it to load. nhw.pl/wp/2009/… – Scott 7 secs [...]

  4. Brian Samson on June 15th, 2009 22:31

    Excellent post, thank you.

  5. Seb on June 24th, 2009 13:01

    n Rails 2.3 you can cause your plugins to be reloaded with each request by adding this to your development.rb file:

    config.reload_plugins = true

    This was possible before, but it required altering Dependencies.load_once_paths and other black magic. I’ve always had issues with these approaches, and so it’s nice to see official support for such a useful feature.

  6. Automatically reload Rails plugins | Yves Vogl on January 12th, 2010 21:24

    [...] code because plugin paths are added to the ActiveSupport::Dependencies.load_once_paths by default. Witold Rugowski suggests adding the plugin to ActiveSupport::Dependencies.explicitly_unloadable_constants and [...]

  7. Automatically reload Rails plugins | Yves Vogl on April 15th, 2010 13:53

    Kramer auto Pingback[...] code because plugin paths are added to the ActiveSupport::Dependencies.load_once_paths by default. Witold Rugowski suggests adding the plugin to ActiveSupport::Dependencies.explicitly_unloadable_constants and [...]

  8. RUBY ON RAILS - Rails issue with reloading gems and plugins in development mode - efreedom on January 20th, 2011 9:16

    Kramer auto Pingback[...] like http://www.williambharding.com/blog/rails/automatically-reload-modules-on-change-in-rails/ and http://nhw.pl/wp/2009/01/07/reloading-your-plugin-in-development-mode but those don’t seem the trick (or I’m doing something wrong.) This question and answers [...]

Leave a Reply