solnic / virtus

[DISCONTINUED ] Attributes on Steroids for Plain Old Ruby Objects
MIT License
3.77k stars 228 forks source link

Cannot have constant named `Collection` within Virtus enabled class. #360

Open stephenprater opened 8 years ago

stephenprater commented 8 years ago

This bug manifests as a mysterious, difficult to track ArgumentError, and is particularly gnarly to track down because it will only happen with "lazily loaded" constants (like for instance the Rails preloader.)

Say you have a setup like this:

class Thing
   include Virtus.model
end

And in a different file:

class Thing::Collection
end

A call that lazily loads the Thing::Collection will result in the argument error because Virtus const_missing extensions will autoload the Virtus::Attributes::Collection constant.

I don't know enough about Virtus internals to really attempt a fix but this key being present in the TypeLookup cache is probably the salient problem.

:Collection => Virtus::Attribute::Collection < Virtus::Attribute

The problem can be mitigated by either changing the name of your Collection class or explicitly requiring it AFTER your class definition has opened like so.

class Thing
   require 'thing/collection'
   include Virtus.model
end