0

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

  • Blacklist the folder from being autoloaded by Zeitwerk?
  • Load it using require or in any other way without wrapping it in modules?
George Morris
  • 433
  • 4
  • 17

1 Answers1

2

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
Hugo Peixoto
  • 3,604
  • 2
  • 18
  • 12