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
.