1

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

1

1 Answer 1

1

Do not define your classes and modules the short-hand way. You run into scoping issues.

module UserPermission class Proposal end end module UserPermission class Template < Proposal end end UserPermission::Template.superclass # => UserPermission::Proposal 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.