Rails 6 with Zeitwerk:如何扩展 Ruby 核心 类,如日期、时间、字符串等
Rails 6 with Zeitwerk: How to Extend Ruby Core Classes like Date, Time, String etc
我正在将 Rails 5.2.2 升级到 Rails 6.0.0,现在有 Zeitwerk。
之前我已经扩展了核心 ruby 类,如日期、时间、字符串、浮点数等,如 this question 中所述。使用初始化文件加载 lib/core_ext/*
文件夹中的所有文件。启动 rails server
时,它现在会出错,堆栈跟踪的最后一行显示为:
/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
等抛出一个它已经被定义的错误(当在 application.rb
中使用 Rails.autoloaders.log!
时)。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
我通过扩展核心功能和在 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 }
正如 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
The lib folder does not belong to the autoload paths since Rails 3. @pixeltrix's is the recommended modern idiom if you want to autoload.
Otherwise, lib belongs to $LOAD_PATH and you can require files in that directory.
我们可以调用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
可以自动加载
我正在将 Rails 5.2.2 升级到 Rails 6.0.0,现在有 Zeitwerk。
之前我已经扩展了核心 ruby 类,如日期、时间、字符串、浮点数等,如 this question 中所述。使用初始化文件加载 lib/core_ext/*
文件夹中的所有文件。启动 rails server
时,它现在会出错,堆栈跟踪的最后一行显示为:
/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
等抛出一个它已经被定义的错误(当在 application.rb
中使用 Rails.autoloaders.log!
时)。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
我通过扩展核心功能和在 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 }
正如 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
The lib folder does not belong to the autoload paths since Rails 3. @pixeltrix's is the recommended modern idiom if you want to autoload. Otherwise, lib belongs to $LOAD_PATH and you can require files in that directory.
我们可以调用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
可以自动加载