I have a standard app that contains of sub-apps that we will slowly migrate into separate gems. The main problem is that each sub-app basically has an almost identical schema and very similar business logic that sometimes is really pretty much the same.
Currently, as a first step, we created a subfolder in lib/client
with a structure like a typical rails app.
As an example, a concern for a ClientA
looks like this/
module Client
module ClientA
module Concerns
module MyConcern
...
end
end
end
This all works fine and gets autoloaded by Zeitwerk.
However, when I want to create an initializer in a Rails way, I don't want to wrap it inside modules and make a class around it and this is where I am getting lib/clients/ClientA/config/initializers/custom_initializer.rb to define constant Clients::ClientA::Config::Initializers::CustomInitializer, but didn't (Zeitwerk::NameError)
This folder gets autoloaded like this
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += %W(#{config.root}/lib/client/**/*)
Is there a way how to
require
or in any other way without wrapping it in modules?You can ignore parts of the project in zeitwerk using Loader#ignore
. You can access rails zeitwerk autoloader via Rails.autoloaders.main
.
So you should be able to add something like this to your application.rb
:
Rails.autoloaders.main.ignore(Rails.root.join('lib/clients/*/config/initializers/*.rb'))
You'll then have to require them manually, maybe in an initializer in the main app directory. You could create a config/initializers/clients.rb
with something like:
Dir[Rails.root.join('lib/clients/*/config/initializers/*.rb')].each do |filename|
require filename
end