I use Rails 6.0.4 with classic autoloader on Ruby 2.7.
With following code,
I found referencing A::B::C::D::E_VARIANT1 in fresh rails console works fine.
However, after reload! ing in console, A::B::C::D::E_VARIANT1 began to fail:
There is no easy solution for that, because Module#autoload uses Kernel#require and therefore is idempotent.
In your project, A::B::C::D::E is an autoloadable constant, and A::B::C::D::E_VARIANT1 is not, but usage does not seem to even refer to ...::E.
You could technically mutate $LOADED_FEATURES in a to_prepare callback, but starts to feel too hacky perhaps.
The easiest way to make this flow with autoloading is to define a file for each constant, either at the same level, or nested (A::B::C::D::E::VARIANT1), and let things autoload by themselves without that extra configuration.
module A
module B
module C
module D
class E; end
class E_VARIANT1 < E; end
class E_VARIANT2 < E; end
end
end
end
end
into app/models/a/b/c/d.rb, then you don’t need Module#autoload either, and everything autoloads and reloads just fine (because in order to reach any E you have first to pass necessarily through A::B::C::D, which loads d.rb, which defines the child constants as a side-effect).
Both proposed solutions work in zeitwerk mode as well.