Closed richardmarbach closed 10 months ago
Hey, sorry for not replying earlier, I just forgot!
When you boot, the loader has to scan the root directories and set autoloads for the first level of things that it finds. For example, given this structure:
app/controllers/users_controller.rb
app/models/user.rb
the loader sets this up on your behalf:
Object.autoload(:UsersController, '/abspath/to/app/controllers/users_controller.rb')
Object.autoload(:User, '/abspath/to/app/models/user.rb')
That is because Object
is the default root namespace, and Object
is something that already exists.
Similarly, if app/models
represented the Foo
namespace, then it would be:
Object.autoload(:UsersController, '/abspath/to/app/controllers/users_controller.rb')
Foo.autoload(:User, '/abspath/to/app/models/user.rb')
That means, the loader needs the Foo
class/module object before things are ready for being autoloaded. That is why a custom root namespace has to be passed at configuration time. And that is why it cannot be a reloadable module, it has to exist, the loader needs the instance to set autoloads on it.
Hey, thanks for taking the time to reply and clearing up the behaviour!
I've recently been adding packwerk to a project, and I settled on using the recommended structure from packs rails with nested packs:
This structure does introduce quite a lot of nested directories, so I tried using
.push_dir("packs/namespace1/packs/sub_namespace/models", namespace: Namespace1::SubNamespace)
to help reduce nesting.Here, I ran across the issue of
namespace1.rb
no longer being loaded. This is a problem in my use case since theNamespace1
module defines theActiveRecord
table prefix:As a workaround, the prefix would need to be added to every model in
namespace1
.This is documented behaviour, but I was wondering if this restriction can be lifted.