5

我最近从 gem 版本切换resources_controller到 aplugin作为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类块中的 a 会命中),但它似乎从未真正调用初始化块本身。这当然很重要,因为这是它扩展ActionController到包含该resources_controller_for方法的地方。

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

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

可能会发生什么?

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

4

1 回答 1

7

您在这里遇到的问题是,一旦初始化程序过程开始,您就无法添加新的初始化程序。

在这里,您需要在初始化程序过程中注册初始化程序的代码。当您在 Gemfile 中使用 gems 时,初始化程序会在以下代码中注册:

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_controllerapplication.rb.

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

gem 'resources_controller', :path => "vendor/plugins/resources_controller"

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

于 2011-12-10T06:13:19.013 回答