How can I automatically reload gem code on each request in development mode in Rails?

亡梦爱人 提交于 2019-12-11 03:47:31

问题


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 files

    spec.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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!