rails 未初始化的常量模块名称

问题描述

我在 app 目录下有一个集成文件夹。 可以看到这个路径被加载了

 ActiveSupport::Dependencies.autoload_paths
 "/appname/app/integrations"

然后在此路径中我有一个带有嵌套模块的文件

"/appname/app/integrations/moduleA/base_service.rb"
# frozen_string_literal: true

module Integrations
  module ModuleA
    class BaseService

但是当我尝试使用该类时

Integrations::moduleA::BaseService
::Integrations::moduleA::BaseService

他们都给了我

NameError: uninitialized constant Integrations

解决方法

rails 自动加载器的工作方式(经典和 Zeitwerk)是 /app 文件夹的直接子目录是“根”目录。这意味着自动加载器将在所有这些目录中查找根级常量。

因此,如果您想定义 Foos::Bar,您需要将文件放在 app/foos/foos/bar.rb 中。

如果您想避免这种情况并将常量放在 app/integrations/module_a/base_service.rb 中,您需要将具有自定义命名空间的目录推送到 Zeitwerk:

loader.push_dir(Rails.root.join('app','integrations'),namespace: Integrations)

对于经典的自动加载器,解决方案是将 /app 文件夹也作为根添加到 autoloading/eager_loading 路径中​​。

config.autoload_paths += %W(#{config.root}/app)

这样自动加载器就会在 Integrations::ModuleA 中查找 app/integrations/module_a.rb

见:

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...