我正在将Rails 5.2.2升级到现在具有Zeitwerk的Rails 6.0.0。
以前,我已经扩展了核心的红宝石类,例如this question中所述的Date,Time,String,Float等。使用初始化程序文件来加载lib/core_ext/*
文件夹中的所有文件。现在开始启动rails server
时,它会错误显示stacktrace的最后一行:
/home/username/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/zeitwerk-2.1.10/lib/zeitwerk/loader.rb:351:in `const_get': uninitialized constant CoreExt::Date (NameError)
不幸的是,Zeitwerk在lib/core_ext/date.rb
等引发已定义错误的地方引发了错误(在Rails.autoloaders.log!
中使用application.rb
时。CoreExt::Date
此后,我将文件直接移动到initializers
(以前,我只有一个初始化器目录,其中包含一个文件,该文件从'lib/core_ext/*
文件夹中加载了每个文件)。目前,此问题已解决,但我想将core_ext
文件夹和文件保留在原来的位置。
我在这里错过了什么?
lib/core_ext/date.rb
class Date
def to_sap
strftime('%d.%m.%Y')
end
end
我曾尝试在CoreExt
中显式包装,但这没有帮助。
module CoreExt
class Date
def to_sap
strftime('%d.%m.%Y')
end
end
end
答案 0 :(得分:2)
在https://github.com/fxn/zeitwerk#file-structure上说
loader.push_dir(Rails.root.join("app/models"))
loader.push_dir(Rails.root.join("app/controllers"))
Zeitwerk作者:https://github.com/rails/rails/issues/37835#issuecomment-560563560
由于Rails 3,lib文件夹不属于自动加载路径。如果要自动加载,建议使用@pixeltrix。 否则,lib属于$ LOAD_PATH,您可以在该目录中需要文件。
我们可以调用push_dir来加载lib子目录。我的解决方案:
# config/initializers/zeitwerk.rb
Rails.autoloaders.main.push_dir(Rails.root.join('lib'))
或
# config/application.rb
...
config.autoload_paths += [
Rails.root.join('lib')
]
然后CoreExt::Date
可以自动加载。
答案 1 :(得分:0)
通过扩展核心功能并在lib/extensions
中添加文件,我具有相同的结构
我通过添加
解决了这个问题# config/application.rb
#
class Application < Rails::Application
...
Rails.autoloaders.main.ignore(Rails.root.join('lib/extensions'))
end
我仍然像以前一样初始化扩展名:
Dir[Rails.root.join('lib', 'extensions', '**', '*.rb')].each { |f| require f }