Railtie 初始化程序未在插件中运行

发布于 2024-12-04 18:13:19 字数 1505 浏览 2 评论 0原文

我最近从 resources_controller 的 gem 版本切换到 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

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 problem exists in development mode.

What may be going on?

For reference, full plugin is here: https://github.com/ianwhite/resources_controller

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一直在等你来 2024-12-11 18:13:19

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

在这里,您需要在初始化程序过程中注册初始化程序的代码。当您在 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 内部的加载路径也在初始化过程中设置,因此您将无法在 中 require resources_controller应用程序.rb。

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文