Rails 6+、zeitwerk 自动加载器和命名空间常量

Dan*_*n L 4 autoload ruby-on-rails-6 zeitwerk

Rails 6+ 的默认自动加载器是 zeitwerk,这似乎比以前的方法有了很大的改进。

但是,zeitwork 遵循 Rails 项目的约定,即其中的任何内容app/*都是自动加载的,不需要命名空间。

这非常app/models/user.rb有用,因为您不必使用Models::User但可以只引用User.

但是,我添加了自己的app/services目录,并将我的服务对象命名为Services::Users::Create,它将映射到app/services/users/create.rb.

Zeitwork 正在抛出我的类常量不存在的错误,因为它是预期的Users::Create(没有Services::前缀)。

无论如何要配置 zeitwork 以Services::在这些实例中要求命名空间?在我看来,阅读代码Services::Users::Create并知道您正在查看app/services/users/create.rb文件要干净得多。

如果只有Users::Create,一般的 Rails 开发人员可能会查找该app/models/users/create.rb文件。

我不喜欢命名它的方法Users::CreateService,它对我来说似乎很不雅。

我不能是唯一一个使用这样的约定的人;有没有其他人遇到过解决方案?我仍在浏览所有 zeitwerk 文档以寻找解决方案,但还没有找到。

小智 5

https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#have-app-in-the-autoload-paths

一些项目想要像 app/api/base.rb 这样的东西来定义 API::Base,并将 app 添加到自动加载路径以在经典模式下完成。由于 Rails 自动将 app 的所有子目录添加到自动加载路径中,我们还有另一种情况,其中存在嵌套的根目录,因此设置不再有效。类似的原理我们在上面解释过。

如果要保留该结构,则需要从初始化程序的自动加载路径中删除子目录:

ActiveSupport::Dependencies.autoload_paths.delete("#{Rails.root}/app/api")
Run Code Online (Sandbox Code Playgroud)