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

Rails模块常量无法与Zeitwerk兼容问题求助

解决方案

Zeitwerk(Rails 6+默认的自动加载器)严格遵循文件名与常量名的映射规则,你遇到的错误正是因为规则不匹配:

  • lib/my_app/version.rb 文件,Zeitwerk会期望它定义 MyApp::Version 常量
  • 但你实际在文件里定义的是 MyApp::VERSION,因此触发 Zeitwerk::NameError

以下是几种符合Zeitwerk规范的合理方案:

方案1:调整常量结构匹配命名规则

把VERSION常量放到MyApp::Version模块下,保持文件名不变:

# lib/my_app/version.rb
module MyApp
  module Version
    VERSION = '3.0.7'
  end
end

之后通过 MyApp::Version::VERSION 访问版本号,同时在application.rb中添加lib目录到自动加载路径:

# config/application.rb
config.autoload_paths << Rails.root.join("lib")

方案2:将VERSION移到MyApp主模块文件

如果希望直接用MyApp::VERSION访问,把常量定义到lib/my_app.rb中:

# lib/my_app.rb
module MyApp
  VERSION = '3.0.7'
end

同样在application.rb中添加lib到自动加载路径,Zeitwerk会自动加载MyApp模块并识别VERSION常量。

方案3:通过主模块文件引入version.rb

保留现有文件结构,在MyApp主模块文件中引入version.rb:

# lib/my_app.rb
module MyApp
  require_relative "my_app/version"
end
# lib/my_app/version.rb
module MyApp
  VERSION = '3.0.7'
end

这种方式既保留了单独的version.rb文件,又让Zeitwerk加载MyApp模块时自动引入VERSION常量,无需在application.rb中直接require。

方案4:自定义Zeitwerk的文件名-常量映射

如果不想修改文件或常量结构,可通过Zeitwerk的inflector自定义映射规则:

# config/application.rb
Rails.application.configure do
  config.autoload_paths << Rails.root.join("lib")

  # 让version.rb映射到VERSION常量
  Rails.autoloaders.main.inflector.inflect(
    "version" => "VERSION"
  )
end

这样Zeitwerk会把lib/my_app/version.rb识别为定义MyApp::VERSION,而非MyApp::Version。

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:18:18