我的问题绝对理论化,比如“这是正确的事吗?”。 我是Rails的新手,特别是Ruby的新手,我正在尝试将Cancan自动化解决方案用于我的Rails appilcation。
让我们考虑一下这样的简单控制器,一对关联视图和一个带DB表的User模型。
class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end
目标是将“索引”方法的访问限制为除管理员之外的所有人,并允许普通用户仅查看他们自己的页面,例如允许id == 5的用户查看页面“users / 5”。 对于这个范围,我为Cancan创建了一个能力类。这是:
class Ability
include CanCan::Ability
def initialize user, options = {}
default_rules
if user
admin_rules(user) if user.role.eql? "admin"
player_rules(user) if user.role.eql? "player"
end
end
def admin_rules user
can :read, UsersController
end
def player_rules user
can :read, User do |user_requested|
user_requested.id == user.id
end
end
def default_rules
end
end
我的问题是: 如果我没有类型User的方便用户,我应该在“can”方法中使用UsersController作为对象吗?稍后通过控制器的“索引”方法中的“authorize!:show,UsersController”来应用它。或者它应该以其他方式完成? 谢谢你的建议。
答案 0 :(得分:2)
不,您不想将UsersController添加到CanCan。
CanCan旨在授权资源,而不是Rails控制器。
我建议如下:
def initialize(user)
if user.is_admin?
can :manage, User
else
can :manage, User, :id => user.id
end
end
这将允许用户仅访问他自己的用户,除非他是管理员。 请参阅CanCan Wiki中的Defining abilities页面
答案 1 :(得分:0)
我使用符号,例如,在Ability类
中def initialize(user)
if user.is_admin?
can :any, :admin
end
end
并在控制器中
authorize! :any, :admin
答案 2 :(得分:0)
+1到@Tigraine。
按照他的指示......
class Ability
include CanCan::Ability
def initialize user, options = {}
default_rules
if user
admin_rules(user) if user.role.eql? "admin"
player_rules(user) if user.role.eql? "player"
end
end
def admin_rules user
can :manage, User
end
def player_rules user
can :manage, User :id => user.id
end
def default_rules
end
end
并在您的控制器中执行此操作...
class UsersController < ApplicationController
load_and_authorize_resource
# => @users for index
# => @user for show
def index
end
def show
end
end
有关load_and_authorize_resource的详细信息,请参阅this link
的底部答案 3 :(得分:0)
在维基中,我找到了另一种设置能力的方法。虽然它有点先进,check it out here。
ApplicationController.subclasses.each do |controller|
if controller.respond_to?(:permission)
clazz, description = controller.permission
write_permission(clazz, "manage", description, "All operations")
controller.action_methods.each do |action|
...