Information on what's going on here in ruby: http://coderrr.wordpress.com/2008/03/11/constant-name-resolution-in-ruby/
Doesn't help me solve my problem.. but it at least explains they 'why'
I've written the following method:
# delegate to a user permission serializer specific to the given object # - if a serializer is not found for the given object, check the superclass # # @raise [NameError] if none of object, or it's superclasses have a known # user permission serializer # @return [UserPermission::*Serializer] returns serialized object def self.serialized_for(object, user, klass: nil, recursion_limit: 5) object_class = klass ? klass : object.class # use demodulize to chop off the namespace and get the generic object name object_name = object_class.name.demodulize # bulid serializer name name = "::UserPermission::#{object_name}Serializer" begin binding.pry permissions = object.user_permissions(user) return name.constantize.new(permissions) rescue NameError => e raise e if recursion_limit < 1 # try with super class UserPermission.serialized_for( object, user, klass: object_class.superclass, recursion_limit: recursion_limit - 1 ) end end The goal is to be able to retrieve the serializer of any subclass, provided the subclass has a superclass with a serializer already defined. (I'm using ActiveModelSerializers, but that's not important here).
My problem is that I'm receiving a non-namespaced class when name.constantize runs.
My existing classes:
- UserPermission
- UserPermission::ProposalSerializer
- PresentationSerializer < ActiveModel::Serializer
- Presentation < Proposal
- Proposal < ActiveRecord::Base
What I'm expecting to happen, is that when I call UserPermission.serialized_for with a Presentation, that name.constantize tries to give me a ::UserPermission::PresentationSerializer and then throw a NameError because the class doesn't exist.
What I'm getting instead is ::PresentationSerializer, which is no good - used for a different purpose.
Here is what I came up with for replicating the issue in irb: (maybe the above context is an overly complicated explanation of this):
class NameSpace; end class NameSpace::Klass; end class Klass; end class SubKlass < Klass; end Object.const_get "::NameSpace::SubKlass" => SubKlass Object.const_get("::NameSpace").const_get("SubKlass") => SubKlass eval("NameSpace::SubKlass") (eval):1: warning: toplevel constant SubKlass referenced by NameSpace::SubKlass => SubKlass Is there a way I can constantize "::NameSpace::SubKlass" such that I get a NameError due to NameSpace::SubKlass not existing?
P.S.: I hope the context helps.
Edit: found another problem:
UserPermission::Template < UserPermission::Proposal UserPermission::Template.superclass => Proposal should be UserPermission::Proposal
UserPermission::Proposal (pry):9: warning: toplevel constant Proposal referenced by UserPermission::Proposal => Proposal UserPermission::Proposal is a class. So... this is a big problem. o.o
I'm using Ruby 2.1.0