Rails 自定义项目结构自动加载配置
Rails custom project structure autoloading configs
我有一个标准应用程序,其中包含我们将慢慢迁移到单独的 gem 中的子应用程序。主要问题是每个子应用程序基本上都有几乎相同的模式和非常相似的业务逻辑,有时甚至非常相似。
目前,作为第一步,我们在 lib/client
中创建了一个子文件夹,其结构类似于典型的 rails 应用程序。
例如,对 ClientA
的关注看起来像这样/
module Client
module ClientA
module Concerns
module MyConcern
...
end
end
end
一切正常,并由 Zeitwerk 自动加载。
但是,当我想以 Rails 的方式创建初始化程序时,我不想将它包装在模块中并在其周围创建一个 class,这就是我得到的地方lib/clients/ClientA/config/initializers/custom_initializer.rb to define constant Clients::ClientA::Config::Initializers::CustomInitializer, but didn't (Zeitwerk::NameError)
此文件夹会像这样自动加载
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += %W(#{config.root}/lib/client/**/*)
有什么办法
- 将 Zeitwerk 自动加载的文件夹列入黑名单?
- 使用
require
或任何其他方式加载它而不将其包装在模块中?
您可以 ignore parts of the project in zeitwerk using Loader#ignore
. You can access rails zeitwerk autoloader 通过 Rails.autoloaders.main
。
所以你应该能够将这样的东西添加到你的 application.rb
:
Rails.autoloaders.main.ignore(Rails.root.join('lib/clients/*/config/initializers/*.rb'))
然后您必须手动要求它们,也许在主应用程序目录的初始化程序中。你可以创建一个 config/initializers/clients.rb
类似的东西:
Dir[Rails.root.join('lib/clients/*/config/initializers/*.rb')].each do |filename|
require filename
end
我有一个标准应用程序,其中包含我们将慢慢迁移到单独的 gem 中的子应用程序。主要问题是每个子应用程序基本上都有几乎相同的模式和非常相似的业务逻辑,有时甚至非常相似。
目前,作为第一步,我们在 lib/client
中创建了一个子文件夹,其结构类似于典型的 rails 应用程序。
例如,对 ClientA
的关注看起来像这样/
module Client
module ClientA
module Concerns
module MyConcern
...
end
end
end
一切正常,并由 Zeitwerk 自动加载。
但是,当我想以 Rails 的方式创建初始化程序时,我不想将它包装在模块中并在其周围创建一个 class,这就是我得到的地方lib/clients/ClientA/config/initializers/custom_initializer.rb to define constant Clients::ClientA::Config::Initializers::CustomInitializer, but didn't (Zeitwerk::NameError)
此文件夹会像这样自动加载
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += %W(#{config.root}/lib/client/**/*)
有什么办法
- 将 Zeitwerk 自动加载的文件夹列入黑名单?
- 使用
require
或任何其他方式加载它而不将其包装在模块中?
您可以 ignore parts of the project in zeitwerk using Loader#ignore
. You can access rails zeitwerk autoloader 通过 Rails.autoloaders.main
。
所以你应该能够将这样的东西添加到你的 application.rb
:
Rails.autoloaders.main.ignore(Rails.root.join('lib/clients/*/config/initializers/*.rb'))
然后您必须手动要求它们,也许在主应用程序目录的初始化程序中。你可以创建一个 config/initializers/clients.rb
类似的东西:
Dir[Rails.root.join('lib/clients/*/config/initializers/*.rb')].each do |filename|
require filename
end