我正在尝试使用Rails 4制作应用程序。
我已经使用Rolify gem定义了一系列角色。
现在,我想使用pundit来允许有角色的用户做某些事情。如果有多种角色可以做某件事,我就定义了一组角色。
在我的application_policy中,我定义了私有方法,它们列出了我想在权威权限中使用的角色组。
我的应用程序策略实例化用户和记录。然后我将记录定义为相关模型的名称(与该模型的策略名称相同)。
我有:
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
scope.where(:id => record.id).exists?
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
private
def cf_legal
[ :Admin, :CF_Legal, :CF_Policy_Manager ]
end
def cf_content
[ :Admin, :CF_Author, :CF_Editor ]
end
end
然后在我的内容政策中,我想说:
def record
content
end
def create
user.has_role? :cf_content
end
当我保存并尝试时,我无法看到我应该看到的东西(作为具有角色作者的用户。
有人能看到怎么做吗?
答案 0 :(得分:2)
tl; dr:在Policy类上使用查询方法。
首先,模型应该拥有自己的Policy类(可选)扩展ApplicationPolicy类。假设您的模型名为Post
。然后你可以做类似的事情:
class PostPolicy < ApplicationPolicy
attr_reader :user, :post
def initialize(user,post)
@user = user
@post = post
end
def create?
cf_content.all? { |role| user.has_role?(role) }
end
private
def cf_content
[ :Admin, :Author, :Editor ]
end
end
class PostsController
def create
@post = Post.new(params[:post])
authorize @post, :create?
# @post.save and redirect, etc.
end
end
授权调用将调用create?
查询方法并检查用户是否具有cf_content中的角色。
您可能甚至不需要添加第二个参数create?
,正如专家documentation所说:
授权方法自动推断Post会有一个 匹配PostPolicy类,并实例化此类,交付 当前用户和给定记录。然后从行动中推断出来 名称,它应该调用更新?在这个政策实例上。
或者在您的情况下,create?
代替update?
。
答案 1 :(得分:1)
您可以检查多个这样的角色:
user.admin?或user.author?
如果您想从阵列中检查角色,您还可以查看:cf_content.include?(user.role)或cf_content.include?(user.role.title),无论哪种情况适合于场景。
您还可以使用 - &gt;检查实例绑定角色。 user.applied_roles并查看它返回的角色是否包含您期望的角色。
答案 2 :(得分:0)
我认为你需要使用
has_any_role?
将两个或多个args作为符号传递。但是你的cf_content方法正在返回一个数组。如果用户需要您在cf_create
中定义的3个角色,则需要执行更类似的操作
def create
cf_content.all? { |role| user.has_role?(role) }
end
更新:
如果你只需要一个角色而不是简单的改变:
def create
cf_content.any? { |role| user.has_role?(role) }
end
另外,我不确定这些代表什么,但如果它们是你角色的名字,我会建议使用小写。而不是
[ :Admin, :CF_Author, :CF_Editor ]
您可以使用:
[:admin,:cf_author,:cf_editor]
更新2:
has_role?不接受数组。所以,如果你想检查has_role?在数组上你需要迭代has_role?在数组中的每个项目。从以下版本开始:cf_content方法返回角色数组,然后从:
更改def create
user.has_role? :cf_content
end
要:
def create
:cf_content.any? { |role| user.has_role?(role) }
end
但是你还没有解释你在试图制定你的内容政策的地方&#34;。