如何在Rails的开发模式下自动为每个请求重新加载gem代码?
我正在开发一个Rails应用程序,其中大部分不是特定于应用程序的代码都是在各种gem中编写的,包括一些Rails引擎和一些我正在增强或修复bug的第三方gem。
gem 'mygem', path: File.expath_path('../../mygem', __FILE__)
由于这些gem中的很多代码实际上都是应用程序的一部分,因此它仍然经常变化。 我希望能够利用Railsfunction,在开发时(即config.cache_classes
为false时)在每个请求上重新加载代码,但这只在默认情况下在普通应用程序结构中完成。
如何配置Rails以在每个请求上重新加载gem代码,就像使用应用程序代码一样?
在ActiveSupport
的帮助下,我通过反复试验发现需要执行几个步骤。
-
将
activesupport
添加为.gemspec
文件中的依赖.gemspec
spec.add_dependency 'activesupport'
-
在gem的顶级模块中包含ActiveSupport :: Dependencies(这是最难以捉摸的要求)
require 'bundler'; Bundler.setup require 'active_support/dependencies' module MyGem unloadable include ActiveSupport::Dependencies end require 'my_gem/version.rb' # etc...
-
设置您的gem以使用自动加载。 您可以手动使用ruby 自动加载声明将符号映射到文件名,也可以使用Rails样式的文件夹结构到模块层次结构规则(请参阅ActiveSupport #constantize )
-
在gem中的每个模块和类中,添加
unloadable
。module MyModule unloadable end
-
在每个依赖于gem中的模块或类的文件中,包括在gem本身中,使用
require_dependency
在每个文件的顶部声明它们。 根据需要查找gem的路径以正确解析路径。require_dependency "#{Gem.loaded_specs['my_gem'].full_gem_path}/lib/my_gem/myclass"
如果在修改文件和发出请求后出现exception,请检查您是否没有错过依赖项。
有关一些有趣的细节,请参阅有关Rails(和ruby)自动加载的这篇综合文章。
- 无法使用cache_classes = true为Concern(ActiveSupport :: Concern :: MultipleIncludedBlocks)定义多个“包含”块
- Bundler找不到gem“activesupport”的兼容版本
- Activesupport / Multi json:“无法识别您的适配器规范”
- rails activesupport通知 – 错误的db运行时值
- ActiveSupport :: JSON.decode无法正确处理文字换行符
- 样式化Rails date_select的日期字段
- 如何从过时的TZInfo标识符中获取Rails TimeZone名称?
- 无法加载require_dependency
- NoMethodError:ActiveSupport的未定义方法`halt_callback_chains_on_return_false =’:模块