I'm refactoring here a classic Rails app into a packages/modularized structure using packwerk. So what used to be:
- app
- services
- foo
turned into:
- packages
- package_name
- services
- foo
I added the following line in application.rb for autoloading:
class Application < Rails::Application
config.load_defaults 6.0
# packwerk files
config.paths.add 'packages', glob: '*/{*,*/concerns}', eager_load: true
Until this point it worked fine and my Foo service was available at Foo.
But when I created a /public folder and moved services there (standard for packwerk):
- packages
- package_name
- public
- services
- foo
it stopped working and calling Foo started throwing unitialized constant error. Same for PackageName::Services::Foo, PackageName::Foo, etc.
Adding zeitwerk.rb initializer in case it's of any help, although I don't see there anything that could be causing the issue:
Rails.autoloaders.each do |autoloader|
# See inflections.rb for inflector rules
autoloader.inflector.inflect(
"ai_wrapper" => "AIWrapper", # ActiveAdmin class
)
# ignore ActiveAdmin classes: without this line zeitwerk will match constants like Documents or DocumentFields
# to /ops/admin classes instead of core/models directories
autoloader.ignore(Rails.root.join('packages/ops/admin'))
end
CodePudding user response:
By adding an intermediate public directory, the wildcard pattern made packages/package_name/public an autoload path, and therefore the constant expected to be defined in that file was now Services::Foo.
In order to define and use the same top-level Foo constant after the introduction of the new directory, the configuration can use a different wildcard pattern so that packages/package_name/public/services becomes an autoload path, or can alternatively stay with packages/package_name/public and collapse services.
