8

How is it possible to force reloading a gem for every request?

I develop a gem and would like to reload my gem's code every time when I refresh the page in a browser. My Gemfile:

gem "my_gem", :path => "../my_gem"

To solve the problem I tried every suggestion listed in stakoverflow. Nothing helped. Also have found two Rails config parameters: watchable_dirs and watchable_files. Tried to use them but they also don't work for me.

Vadim
  • 349
  • 2
  • 7
  • 3
    Someone's got to ask: *Why?* What problem are you trying to solve? – Jordan Running Feb 12 '12 at 02:14
  • 5
    @Jordan question is obvious: because he is developing a gem, he wants to change and debug it seamlessly. – apneadiving Feb 12 '12 at 09:29
  • I guess, you should require your gem with a `to_prepare` statement in it's initializer file, see http://guides.rubyonrails.org/configuring.html#initialization-events – apneadiving Feb 12 '12 at 09:39
  • @apneadiving I've tried two options in development.rb: (1) `MyApp::Application.configure do config.to_prepare do require "../my_gem/lib/my_gem/helper.rb" end end` (2) `ActionDispatch::Callbacks.to_prepare do require "../my_gem/lib/my_gem/helper.rb" end` Nothing helps. What is wrong? – Vadim Feb 12 '12 at 11:03
  • @apneadiving If you look at the revision history you'll see that it was not initially obvious, although that was certainly my guess. – Jordan Running Feb 12 '12 at 22:38

2 Answers2

2

I’ve done quote a bit of hunting around for this, but in the end it took some trial and error.

lib/my_gem/my_gem.rb:

require 'active_support/dependencies'
ActiveSupport::Dependencies.autoload_paths += [File.expand_path("..", __FILE__)]

module MyGem
  include ActiveSupport::Dependencies
  unloadable
end

Be sure to add “unloadable” to all of your classes as well.

aceofspades
  • 7,568
  • 1
  • 35
  • 48
2

You should mark the classes you want to reload as unloadable using ActiveSupport::Dependencies unloadable method;

class YourClass
  unloadable
end

http://apidock.com/rails/ActiveSupport/Dependencies/Loadable/unloadable and http://robots.thoughtbot.com/post/159805560/tips-for-writing-your-own-rails-engine

should give you some background. Alternatively you can do your own reloading like this;

Object.send(:remove_const, 'YOUR_CLASS') if Object.const_defined?('YOUR_CLASS')
GC.start
load 'path/to/your_file.rb'
james2m
  • 1,562
  • 12
  • 15
  • the problem is that I build a module and then include it into ActionView: `ActionView::Base.send :include, MyGem::Helper`. So I don't have classes. In this case where I should use method 'unloadable'? – Vadim Mar 19 '12 at 17:29
  • Perfect, this solved the problem for me! I just put `unloadable if Rails.env.development?` into my module, and it works like a charm. Thank you! – Joshua Muheim Sep 06 '12 at 06:37