Reputation: 31
I am trying to figure out an issue I am having with my rails app that involves namespacing some sti models.
Originally, I had a collection of sti models located in: app/models/foo I validated these models against json schemas located in app/models/schemas I tested these models from specs in spec/models/foo with factories from spec/factories/foo
My primary model Primary (from which the sti models are linked) did have a method that points to the schemas directory to load everything up.
As is, all is well.
However, I figured I would do something "simple" and move my schemas into a categorized subdirectory to match that of the models, specs, and factories. Seemed like a smart idea.
So, I imagined that I would need to figure out a way to take my sti models, and derive a way to generate the proper path for the schemas so that it looks in the right directory based on its category. For now, I have bar, but in the future I plan on adding baz and qux.
Searching online, it seemed like the first/easiest solution is to namespace the models. That way I can pull that namespace to generate the directory name in my method to point at the json schema path. At least, that is the idea. I don't get far enough to try this out.
So, I namespace one of my models:
module Foo
class Bar < ::Primary
..
end
which matches my file structure (models/foo/bar.rb)
But when I try to check my Zeitwerk or enter a console I get the error: expected file /../app/models/foo/bar.rb to define constant Bar, but didn't.
I was reading online and found solutions that involved creating a foo.rb file in my app/models directory containing a empty module for Foo, but that didn't work either.
(The Zeitwerk documentation seems to imply that this file is not needed)
Specifically, the documentation says (in explicit namespaces):
Classes and modules that act as namespaces can also be explicitly defined, though. For instance, consider
app/models/hotel.rb -> Hotel app/models/hotel/pricing.rb -> Hotel::Pricing
There, app/models/hotel.rb defines Hotel, and thus Zeitwerk does not autovivify a module.
The classes and modules from the namespace are already available in the body of the class or module defining it:
class Hotel < ApplicationRecord include Pricing # works ... end
So, according to the error, Zeitwerk is expecting bar.rb to define constant Bar, but didn't. If I explicitly create the definition - Bar = Foo::Bar then everything works. However, this seems like something isn't right. I would imagine from the documentation that this shouldn't be needed.
I get that technically, Bar is not being explicitly defined (as it is contained within the module Foo) but the documentation seems to point to that format.Obviously, I am missing something.
So, I guess I am looking for clarification on how I should be namespacing these models to get them to work. Or, should I not even attempt to namespace the models and use a different approach to allow for me to match the file structure of the json schemas to that of my models/specs/factories instead of dumping everything in one directory?
For what it is worth, I am using Rails 7.0.8.4. I did see that Rails 7.1x seems to have improved namespace support for core directories like /lib but I don't know if upgrading to 7.1x would make any difference.
Upvotes: 1
Views: 123