在使用Ruby gem Pundit时,我意识到我不确定某些命名空间在Ruby中的工作方式,我不喜欢神秘/不确定性。
Pundit建议你设置一个application_policy.rb
:
class ApplicationPolicy
class Scope
.
.
.
end
end
课堂内实际发生的事情并不重要,只是课程的结构。
然后为从ApplicationPolicy
继承的特定资源指定策略,例如post_policy.rb
:
class PostPolicy < ApplicationPolicy
class Scope < Scope
end
end
我的一般问题是,在PostPolicy
内,当我声明Scope < Scope
时,父Scope
提到了什么?它是否会在外部类的父级中自动命名?那么它与继承ApplicationPolicy::Scope
基本相同吗?我无法找到自己回答这个问题的方法,谢谢!
答案 0 :(得分:4)
很容易让自己:
class C1; class Nested; end; end
class C2<C1; class Nested<Nested; end; end
C2::Nested.ancestors
#⇒ [
# [0] C2::Nested < C1::Nested,
# [1] C1::Nested < Object,
# [2] Object < BasicObject,
# [3] PP::ObjectMixin,
# [4] Kernel,
# [5] BasicObject
# ]
所以,是的,它隐含地解决了ApplicationPolicy::Scope
。
答案 1 :(得分:4)
你是对的。您可以使用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]
以上代码与:
完全相同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]
请注意,PostPolicy::Scope
不会从PostPolicy
继承。它们是独立的类,前者恰好在后者的命名空间中定义。
class A
class Scope
end
end
class B < A
class Scope < Scope
end
end
class C
class Scope < Scope
end
end
失败了:
namespace.rb:26:in `<class:C>': uninitialized constant C::Scope (NameError)
from namespace.rb:25:in `<main>'
这意味着Scope
必须来自A
名称空间。