You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails运行一段时间后无法找到自定义类问题求助

解决Rails中自定义模块/类出现uninitialized constant A::B的问题

这个问题我之前也碰到过,根源大多是Rails自动加载机制(尤其是默认的Zeitwerk加载器)和手动require语句的冲突,结合你的代码和场景,给你几个排查和解决的思路:

1. 移除手动require_relative,遵循Zeitwerk的命名约定

Rails 6及以后默认使用Zeitwerk作为自动加载器,它依赖文件结构与模块/类命名严格对应的规则,不需要手动写require语句。你的当前结构是:

classes/
├── a.rb
└── b/
    └── b.rb

但按照Zeitwerk的规则,A::B类对应的文件应该放在classes/a/b.rb(模块A对应a.rb,它的嵌套类B要放在a目录下的b.rb)。调整目录结构后,直接删掉a.rb里的require_relative './b/b.rb',Zeitwerk会自动在需要的时候加载A::B。

2. 确认自动加载路径配置的规范性

在application.rb里,推荐用更规范的写法配置自动加载路径:

config.autoload_paths << Rails.root.join("classes")

另外,如果你用的是Rails 7+,可以考虑用config.autoload_lib(ignore: %w(assets tasks))这类专门的配置,但autoload_paths对于自定义classes目录依然有效。

3. 排查开发环境的代码重载冲突

开发环境下,Rails会自动重载修改过的文件。当你手动用require_relative加载B类时,第一次启动没问题,但当a.rb被修改重载时,require_relative不会再次执行,导致重新加载的A模块找不到B类。移除手动require后,Zeitwerk会在A::B被引用时自动触发加载,避免重载时的依赖丢失。

4. 用Zeitwerk检查工具验证配置

运行Rails内置的Zeitwerk检查命令,能快速找出命名和文件结构不匹配的问题:

bin/rails zeitwerk:check

如果有不符合规则的地方,这个命令会给出明确的提示,帮你快速定位问题。

5. 生产环境预加载的验证

生产环境下,Rails会预加载所有自动加载路径中的文件。如果文件结构不对,预加载阶段可能没加载到A::B,导致运行时出错。你可以在部署前先本地运行生产环境的预加载检查:

RAILS_ENV=production bin/rails runner "puts A::B"

如果这个命令报错,说明预加载时没加载到B类,需要回到文件结构的调整上。

内容的提问来源于stack exchange,提问作者bo-oz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:10:47