Rails 7 通过引擎将方法自动加载到控制器中

问题描述 投票:0回答:1

我正在考虑将我最喜欢的 CMS 之一更新到 Rails 7,该 CMS 已存档在 github (PushType) 上。只是我自 Rails 6 以来就没有编写过 Rails 代码了。显然,Rails 7 中有关自动加载方法的某些内容发生了变化。我收到此错误:

NameError: uninitialized constant PushType::ApplicationControllerMethods
          include PushType::ApplicationControllerMethods
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

对于引擎中的这条线:

      initializer 'push_type.application_controller' do
        ActiveSupport.on_load :action_controller do
          # ActionController::Base.send :include, PushType::ApplicationControllerMethods
          include PushType::ApplicationControllerMethods
        end
      end
  • 引擎位于root/core/lib/push_type/core/engine.rb
  • 相关控制器方法的定义位置位于:root/core/app/controllers/concerns——在关注目录命名空间中应该可以工作,但事实并非如此,在控制器关注目录中,方法可以在push_type/中找到application_controller_methods.rb

由于我没有接触过语言,我不知道自己在做什么。但在我尝试解决这个问题时,我尝试自动加载涉及 gem 引擎中的目录,如下所示:

    config.autoload_paths << File.expand_path("../../../app/controllers/concerns", __FILE__) <<
                             # File.expand_path("../../../app/controllers/concerns/push_type", __FILE__)
                             File.expand_path("../../../app/helpers", __FILE__)

完整的engine.rb文件如下所示:

module PushType
  module Core
    class Engine < ::Rails::Engine
      isolate_namespace PushType
      engine_name 'push_type'

      config.autoload_paths << File.expand_path("../../../app/controllers/concerns", __FILE__) <<
                             # File.expand_path("../../../app/controllers/concerns/push_type", __FILE__)
                             File.expand_path("../../../app/helpers", __FILE__)

      # config.autoload_paths << "#{root}/app/controllers/concerns" <<
      #                         "#{root}/app/controllers/concerns/push_type" <<
      #                         "#{root}/app/helpers"

      # lib = root.join("lib")
      # config.autoload_once_paths.ignore(
      #   lib.join("assets"),
      #   lib.join("tasks"),
      #   lib.join("generators")
      # )

      config.generators do |g|
        g.assets false
        g.helper false
        g.test_framework  :test_unit, fixture: false
        g.hidden_namespaces << 'push_type:dummy' << 'push_type:field'
      end

      config.assets.precompile += %w(
        *.gif *.jpg *.png *.svg *.eot *.ttf *.woff *.woff2
      )

      config.to_prepare do
        Rails.application.eager_load! unless Rails.application.config.cache_classes
      end

      initializer 'push_type.dragonfly_config' do
        PushType.config.dragonfly_secret ||= Rails.application.secrets.secret_key_base
        PushType.dragonfly_app_setup!
      end

      initializer 'push_type.application_controller' do
        ActiveSupport.on_load :action_controller do
          # ActionController::Base.send :include, PushType::ApplicationControllerMethods
          include PushType::ApplicationControllerMethods
        end
      end

      initializer 'push_type.menu_helpers' do
        ActiveSupport.on_load :action_view do
          include PushType::MenuBuilder::Helpers
        end
      end
    end
  end
end
ruby-on-rails autoload ruby-on-rails-7 rails-engines zeitwerk
1个回答
0
投票

现在还为时过早,Rails 7 中还没有准备好自动加载可重载代码。

然而,碰巧的是,这是一个陷阱。这就是为什么 Rails 7 不允许那么早访问可重载类。由于该模块包含在不可重新加载的类中(

AC::Base
),因此可重新加载是没有意义的,因为重新加载对该包含的模块没有任何影响。

请删除自定义的

autoload_paths
配置,并将引擎的关注点和帮助程序目录添加到
autoload_once_paths
。该集合中的不可重新加载的类和模块更早可用。

© www.soinside.com 2019 - 2024. All rights reserved.