问题
I am developing a Rails app where most of the code not specific to the app has been written inside of various gems, including some Rails engines and some 3rd party gems for which I am enhancing or fixing bugs.
gem 'mygem', path: File.expath_path('../../mygem', __FILE__)
Since a lot of the code in these gems is really part of the app, it's still changing frequently. I'd like to be able to utilize the Rails feature where code is reloaded on each request when in development (i.e. when config.cache_classes
is false), but this is only done within the normal application structure by default.
How can I configure Rails to reload gem code on each request, just like with the app code?
回答1:
I have found through trial and error that several steps are required, with the help of ActiveSupport
.
Add
activesupport
as a dependency in the.gemspec
filesspec.add_dependency 'activesupport'
Include ActiveSupport::Dependencies in the top-level module of your gem (this was the most elusive requirement)
require 'bundler'; Bundler.setup require 'active_support/dependencies' module MyGem unloadable include ActiveSupport::Dependencies end require 'my_gem/version.rb' # etc...
Set up your gem to use autoloading. You an either manually use ruby autoload declarations to map symbols into filenames, or use the Rails-style folder-structure-to-module-hierarchy rules (see ActiveSupport #constantize)
In each module and class in your gem, add
unloadable
.module MyModule unloadable end
In each file that depends on a module or class from the gem, including in the gem itself, declare them at the top of each file using
require_dependency
. Look up the path of the gem as necessary to properly resolve the paths.require_dependency "#{Gem.loaded_specs['my_gem'].full_gem_path}/lib/my_gem/myclass"
If you get exceptions after modifying a file and making a request, check that you haven't missed a dependency.
For some interesting details see this comprehensive post on Rails (and ruby) autoloading.
来源:https://stackoverflow.com/questions/22463012/how-can-i-automatically-reload-gem-code-on-each-request-in-development-mode-in-r