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文档以寻找解决方案,但尚未找到解决方案。
答案 0 :(得分:0)
https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#having-app-in-the-autoload-paths
一些项目想要app / api / base.rb之类的东西来定义API :: Base,然后将app添加到自动加载路径中以经典模式完成该任务。由于Rails会自动将应用程序的所有子目录添加到自动加载路径中,因此我们还有另一种情况,其中存在嵌套的根目录,因此设置不再起作用。我们在上文中曾解释过类似的原则,但很受关注。
如果要保留该结构,则需要从初始化程序的自动加载路径中删除子目录:
ActiveSupport::Dependencies.autoload_paths.delete("#{Rails.root}/app/api")
答案 1 :(得分:0)
除了integrations
,我还需要类似的东西。我也不想将类称为Integrations::Base
,而是将其命名为Integration::Base
。
我使用以下内容创建了文件config/initializers/integrations.rb
:
ActiveSupport::Dependencies.autoload_paths.delete("#{Rails.root}/app/integrations")
autoloader = Rails.autoloaders.main
autoloader.push_dir(Rails.root.join("app"))
autoloader.inflector.inflect "integrations" => "Integration"
然后使用以下方法创建app/integrations/base.rb
:
module Integration
class Base
end
end