Railtie Initializer not running in plugin
I recently switched from the gem version of resources_controller
to a plugin
as the gem
version relied on git
.
Inside the vendor/plugins/plugin/lib/plugin.rb
file, the Railtie
is as follows:
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
I've added a require 'resources_controller'
in one of my initializers and it's properly loading this file. The problem is that although the Railtie
is evaluated (a puts
in the class block will hit), it never seems to actually call the initializer block itself. This is important of course as this is where it extends ActionController
to include the resources_controller_for
method.
This question is appears to have come up here and here. Though in both cases they found other ways around the problem and no direct answer was given for why the block wasn't being called.
From what I can tell in the Rails docs you can name your initializer block anything you'd like and it should run. I don't think it matters, but I first noticed the problem when running in production rails s -e production
though I believe the same p开发者_StackOverflowroblem exists in development mode.
What may be going on?
For reference, full plugin is here: https://github.com/ianwhite/resources_controller
The problem you're having here is that you can't add new initializers once the initializer process has started.
Here, you're requiring the code that registers the initializers during the initializer process. When you use gems in the Gemfile, the initializers are registered in this code:
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
This code executes before the initializers begin. In contrast, you are requiring the resources_controller
code in an initializer file, which runs during the initialization process. As a result, it's too late to register new initializers.
What complicates the situation is that the load paths inside vendor/plugins
are also set up during the initialization process, so you won't be able to require resources_controller
in application.rb
.
The easiest solution to your problem would be to use the :path
feature in bundler. After installing the plugin, add this line to your Gemfile:
gem 'resources_controller', :path => "vendor/plugins/resources_controller"
You can then remove the require line from your initializer, and bundler will recognize that the plugin is a locally checked out gem and do what it would do if you used git.
精彩评论