Railtie Initializer未在插件中运行

时间:2011-09-14 20:50:58

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-plugins railtie

我最近从resources_controller的gem版本切换到plugingem版本依赖于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方法的地方。

这个问题似乎出现了herehere。虽然在这两种情况下他们都找到了解决问题的其他方法,并没有直接回答为什么没有调用该块。

从我在Rails文档中可以看出,您可以将初始化程序块命名为您想要的任何内容,并且它应该运行。我认为这不重要,但我在生产rails s -e production中运行时首先注意到了这个问题,但我相信在开发模式中存在同样的问题。

可能会发生什么?

供参考,完整插件位于:https://github.com/ianwhite/resources_controller

1 个答案:

答案 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时的操作。