dry-core
dry-core copied to clipboard
Constant being resolved as anonymous class
Hello!
I have a Rails application which has some unusual behaviour when paired with dry-core.
Here's the branch that replicates the issue. If you clone down this app with this branch and run:
bundle install
DISABLE_SPRING=1 rails runner projects.rb
Then you will see the issue that I am facing. It's a two-parter:
- The class of instance that is returned by
repo.all.firstshould be aProjects::Project, and it is... but it's seemingly coming fromDry::Core::ClassBuilder, rather than the one defined in the application. - The instance should respond to a
to_modelcall, but it doesn't. This call should be inherited fromApplicationModel, by way of theProjects::Projectclass within the application.
So in effect, both of the last statements in projects.rb should return true if this code is working as it should.
To attempt to work around this, I've tried doing require "projects/project" in project_repository.rb, but this flips it around:
- It defines the class as an anonymous class.
- The instance does respond to a
to_modelcall.
The source of this problem appears to be this code within ClassBuilder:
https://github.com/dry-rb/dry-core/blob/3b26625861b131f85106280e2b38647f8200db11/lib/dry/core/class_builder.rb#L69-L77
In particular:
https://github.com/dry-rb/dry-core/blob/3b26625861b131f85106280e2b38647f8200db11/lib/dry/core/class_builder.rb#L73
If I remove the if statement from this line and manually require the projects/project file in my ProjectRepository class, everything works correctly, at least in my application.
That line -- in its entirety -- was added in abdb106a23528774828a97dc1002d0ed0af33f70, but the reasoning for this is opaque to me. Seems to be fixing / working around some sort of Ruby bug that only existed pre-Ruby 2.4? Well, my app is using Ruby 2.5 so this line doesn't do anything.
I'm betting this is going to be down to some weird combination between dry-core and Rails' own auto-loading mumbo-jumbo. I'd just like to get an expert opinion before I go blaming Rails (again).
I suspect if I turn eager_load to true in both development.rb and test.rb it would work around my problem, but I want to see if there's another potential solution first.