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/**/*)

有什么办法

您可以 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