While working with the Ruby gem Pundit, I realized I was unsure of the way some namespacing works within Ruby and I do not like mysteries/uncertainties in my mind.
Pundit suggests you set up an application_policy.rb
as so:
class ApplicationPolicy
class Scope
.
.
.
end
end
What actually is happening inside of the class doesn't matter, just the structure of the classes do.
Then you specify a policy for a particular resource that inherits from ApplicationPolicy
, say post_policy.rb
as so:
class PostPolicy < ApplicationPolicy
class Scope < Scope
end
end
My general question is, inside my PostPolicy
, when I declare that Scope < Scope
, what does the parent Scope
refer to? Does it automatically get namespaced within the parent of the outer class? So is it essentially the same as inheriting from ApplicationPolicy::Scope
? I am having trouble finding a way to answer this on my own, thanks!
You are right on both counts. You can check it with Class#ancestors
:
class ApplicationPolicy
class Scope
end
end
class PostPolicy < ApplicationPolicy
class Scope < Scope
end
end
p PostPolicy::Scope.ancestors
#=> [PostPolicy::Scope, ApplicationPolicy::Scope, Object, Kernel, BasicObject]
The above code is exactly the same as :
class ApplicationPolicy
end
class ApplicationPolicy::Scope
end
class PostPolicy < ApplicationPolicy
end
class PostPolicy::Scope < ApplicationPolicy::Scope
end
p PostPolicy::Scope.ancestors
#=> [PostPolicy::Scope, ApplicationPolicy::Scope, Object, Kernel, BasicObject]
Note that PostPolicy::Scope
doesn't inherit from PostPolicy
. They are independant classes, the former just happens to be defined in the namespace of the latter.
class A
class Scope
end
end
class B < A
class Scope < Scope
end
end
class C
class Scope < Scope
end
end
fails with :
namespace.rb:26:in `<class:C>': uninitialized constant C::Scope (NameError)
from namespace.rb:25:in `<main>'
It means that Scope
must come from A
namespace.