我最近从resources_controller
的gem版本切换到plugin
,gem
版本依赖于git
。
在vendor/plugins/plugin/lib/plugin.rb
文件中,Railtie
如下:
module Ardes
module ResourcesController
class Railtie < Rails::Railtie
initializer 'ardes.resources_controller' do
ActiveSupport.on_load(:action_controller) do
extend Ardes::ResourcesController
include Ardes::ResourcesController::RequestPathIntrospection
end
ActiveSupport.on_load(:active_record) do
include Ardes::ActiveRecord::Saved
end
end
end
end
end
我在其中一个初始化程序中添加了require 'resources_controller'
,并正确加载此文件。问题是虽然Railtie
被评估(类块中的puts
将会命中),但它似乎永远不会实际调用初始化块本身。这当然很重要,因为这是扩展ActionController
以包含resources_controller_for
方法的地方。
这个问题似乎出现了here和here。虽然在这两种情况下他们都找到了解决问题的其他方法,并没有直接回答为什么没有调用该块。
从我在Rails文档中可以看出,您可以将初始化程序块命名为您想要的任何内容,并且它应该运行。我认为这不重要,但我在生产rails s -e production
中运行时首先注意到了这个问题,但我相信在开发模式中存在同样的问题。
可能会发生什么?
答案 0 :(得分:6)
您在这里遇到的问题是,初始化程序进程开始后您无法添加新的初始化程序。
在这里,您需要在初始化过程中注册初始值设定项的代码。在Gemfile中使用gem时,初始值设定项在以下代码中注册:
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
此代码在初始化程序开始之前执行。相反,您需要初始化文件中的resources_controller
代码,该文件在初始化过程中运行。结果,注册新的初始化器为时已晚。
使情况复杂化的是vendor/plugins
内的加载路径也在初始化过程中设置,因此您无法在resources_controller
中需要application.rb
。
解决您问题的最简单方法是在bundler中使用:path
功能。安装插件后,将此行添加到您的Gemfile:
gem 'resources_controller', :path => "vendor/plugins/resources_controller"
然后,您可以从初始化程序中删除require行,Bundler将识别该插件是本地检出的gem并执行使用git时的操作。