gpt4 book ai didi

ruby-on-rails - 使用 Zeitwerk 自动加载器在 Rails 6 中命名空间服务对象

转载 作者:行者123 更新时间:2023-12-04 13:12:50 28 4
gpt4 key购买 nike

Rails 6 切换到 Zeitwerk 作为默认自动加载器。 Zeitwerk 将加载/app 文件夹中的所有文件,无需命名空间。这意味着,现在可以直接调用 app/services/demo/test_service.rb 中的 TestService 服务对象,例如TestService.new().call .
然而,命名空间有助于在更复杂的 Rails 应用程序中组织对象,例如API::UsersController ,或者对于我们使用 Registration::CreateAccount、Registration::AddDemoData 等的服务。
一种解决方案 suggested by the rails guide是从 application.rb 中的自动加载器路径中删除路径,例如config.autoload_paths -= Dir["#{config.root}/app/services/demo/"] .然而,这感觉就像一个猴子补丁,用于硬塞旧方式或将对象组织到新的 rails 方式中。
命名空间对象或 rails 6 组织它的正确方法是什么,而不仅仅是强制 rails 进入旧方式?

最佳答案

说 Zeitwerk 消除了“命名空间的需要”是不正确的。 Zeitwerk 确实会自动加载 app 的所有子目录(除了 assetsjavascriptsviews )。 app 下的任何目录加载到“根”命名空间中。但是,Zeitwerk 还为这些根目录下的任何目录“自动激活”模块。所以:

/models/foo.rb => Foo
/services/bar.rb => Bar
/services/registration/add_demo_data.rb => Registration::AddDemoData
如果您已经习惯从“非标准”目录加载常量(通过添加到 config.autoload_paths ),通常不会有太大变化。不过,有几种情况确实需要进行一些调整。第一个是您正在迁移仅添加 app 的项目的位置。自身到自动加载路径。在经典(Rails 6 之前)中,这允许您使用 app/api/base.rb包含 API::Base ,而在 Zeitwerk 中,它希望它只包含 Base .这就是您在上面提到的情况,建议从自动加载路径中排除该目录。另一种选择是简单地添加一个包装目录,如 app/api/api/base.rb .
要注意的第二个问题是 Zeitwerk 如何从文件名中推断常量。从 Rails 迁移指南:

classic mode infers file names from missing constant names(underscore), whereas zeitwerk mode infers constant names from filenames (camelize). These helpers are not always inverse of each other,in particular if acronyms are involved. For instance, "FOO".underscoreis "foo", but "foo".camelize is "Foo", not "FOO".


所以, /api/api/base.rb实际上等于 Api::Base在 Zeitwerk,而不是 API::Base .
Zeitwerk 包含一个 rake 任务来验证项目中的自动加载:
% bin/rails Zeitwerk:check
Hold on, I am eager loading the application.
expected file app/api/base.rb to define constant Base

关于ruby-on-rails - 使用 Zeitwerk 自动加载器在 Rails 6 中命名空间服务对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63257854/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com