Rails 4.1.16
Ruby 2.2.7
I have this ActiveRecord model:
class Something::Type < ActiveRecord::Base
When referencing the model like this:
Something::Type.find_by_whatever("test")
I get the following error:
NoMethodError: undefined method `find_by_whatever' for ActiveRecord::AttributeMethods::Serialization::Type:Class
I understand that Ruby constants are broken up, so that Type exists as its own constant, and the autoloader is finding ActiveRecord::AttributeMethods::Serialization::Type first.
However, referencing the namespace in an "absolute" way (prefixing with colons) is supposed to solve the issue, but the result is the same. Any ideas why?
::Something::Type.find_by_whatever("test")
NoMethodError: undefined method `find_by_whatever' for ActiveRecord::AttributeMethods::Serialization::Type:Class
The problem when you define a class with the scope resultion operator is that the module nesting is resolved to the point of definition (the point where you use the module keyword). If you look at the module nesting:
The class not even really nested in the Something module. Which will give you an extremely surprising constant lookup:
Instead you should ALWAYS declare namespaced classes with explicit nesting:
Which gives the module nesting
[Something::Type, Something]which means that it will properly look up constants in the same Something namespace.This is something that the old classic autoloader tended to gloss over as it relied on monkeypatching
Module#const_missing. Zeitwork does not so do it right.