Railtie Initializer未在插件中运行

Kri*_* PD 4 ruby-on-rails ruby-on-rails-plugins ruby-on-rails-3 railtie

我最近从gem版本切换resources_controller到了依赖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
Run Code Online (Sandbox Code Playgroud)

我已经require 'resources_controller'在我的一个初始化程序中添加了一个并正确加载此文件.问题是虽然Railtie被评估(puts类块中的一个将被击中),但它似乎永远不会实际调用初始化块本身.这当然很重要,因为这是扩展ActionController到包括resources_controller_for方法的地方.

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

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

可能会发生什么?

作为参考,完整的插件在这里:https://github.com/ianwhite/resources_controller

Yeh*_*atz 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
Run Code Online (Sandbox Code Playgroud)

此代码在初始化程序开始之前执行.相反,您需要resources_controller初始化程序文件中的代码,该文件在初始化过程中运行.结果,注册新的初始化器为时已晚.

使情况复杂化的是内部的加载路径vendor/plugins也在初始化过程中设置,因此您将无法resources_controller进入application.rb.

解决您问题的最简单方法是:path在bundler中使用该功能.安装插件后,将此行添加到您的Gemfile:

gem 'resources_controller', :path => "vendor/plugins/resources_controller"
Run Code Online (Sandbox Code Playgroud)

然后,您可以从初始化程序中删除require行,并且bundler将识别该插件是本地检出的gem并执行使用git时将执行的操作.