Rails 6 升级遇 Zeitwerk 未初始化常量问题求助
解决Rails 6升级中
Container::MyModuleA未初始化常量问题 问题原因
- 模块结构与目录不匹配:代码里
MyClass定义在顶级MyModuleA模块中,但调用时使用了Container::MyModuleA::MyClass,Zeitwerk会根据container目录自动映射为Container模块,两者结构不对应。 - 加载路径配置冗余:同时添加
lib/container和lib/container/my_module_a到eager_load_paths,会导致Zeitwerk的模块加载逻辑混乱,冗余路径无必要。
解决方案
1. 修正代码的模块嵌套结构
修改lib/container/my_module_a/my_class.rb的内容,将MyModuleA嵌套到Container模块中,与目录结构对应:
module Container module MyModuleA class MyClass # 原有定义... end end end
如果class_two.rb存在同样问题,需同步修改为Container::MyModuleA::ClassTwo的嵌套结构。
2. 清理冗余的加载路径配置
修改config/application.rb,仅保留lib/container作为加载路径:
config.eager_load_paths += %W[ #{config.root}/lib/container ]
3. 验证配置并重启服务
- 运行
bin/rails zeitwerk:check确认输出“All is good!” - 重启
rails server,再次调用Container::MyModuleA::MyClass.new(...)即可正常加载。
补充说明
Zeitwerk的核心规则是目录/文件名与模块/类名严格对应:
container目录 →Container模块container/my_module_a目录 →Container::MyModuleA模块container/my_module_a/my_class.rb文件 →Container::MyModuleA::MyClass类
之前zeitwerk:check显示正常,是因为它仅检查加载路径下的文件是否符合单级命名约定(my_module_a对应MyModuleA),但未检测到调用时的嵌套结构与实际代码的不匹配。
内容的提问来源于stack exchange,提问作者valk
相关产品推荐
相关产品推荐

