Railtie Initializer не работает в плагине - PullRequest
4 голосов
/ 15 сентября 2011

Я недавно переключился с версии gem resources_controller на 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.

Этот вопрос, похоже, возник здесь здесь и здесь . Хотя в обоих случаях они нашли другие пути решения проблемы, и прямого ответа на вопрос, почему блок не вызывается, не было дано.

Из того, что я могу сказать в документации по Rails, вы можете назвать свой блок инициализатора как угодно, и он должен работать. Я не думаю, что это имеет значение, но я впервые заметил проблему при работе в рабочей среде rails s -e production, хотя я считаю, что та же проблема существует в режиме разработки.

Что может происходить?

Для справки, полный плагин здесь: https://github.com/ianwhite/resources_controller

1 Ответ

6 голосов
/ 10 декабря 2011

Проблема, с которой вы столкнулись, заключается в том, что вы не можете добавить новые инициализаторы после запуска процесса инициализации.

Здесь вам требуется код, который регистрирует инициализаторы во время процесса инициализации. Когда вы используете гем в Gemfile, инициализаторы регистрируются в этом коде:

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.

Самое простое решение вашей проблемы - использовать функцию :path в компоновщике. После установки плагина добавьте эту строку в ваш Gemfile:

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

Затем вы можете удалить строку require из вашего инициализатора, и bundler распознает, что плагин является локально извлеченным гемом, и сделает то, что сделал бы, если бы вы использовали git.

...