我试图在授权方面更好地理解CanCan的功能。想象一下这个控制器动作:
def update
if can? :action, Model or can? :resolve, Model or can? :authorize, AnotherModel
# My Code here
respond_with @model
else
raise CanCan::AccessDenied.new(nil, :update, Model)
end
end
我在尝试使用authorize!
找到上述解决方案时达到了这一点。据我所知(也看签名)authorize!
只接受一个权限(动作)和一个主题,并带有可选消息,如下所示:
def authorize!(action, subject, *args)
# code
end
有没有一种方法可以忽略指示授权检查多项操作?将两个一个接一个地授权将在权限之间充当AND
条件,我希望它像OR
条件一样工作,基本上类似于上面的自定义代码(具有以下问题)提高CanCan中的AuthorizationNotPerformed
,可以使用skip_authorize_resource
来避免,这不是我真正想做的事情。
答案 0 :(得分:2)
您可以根据需要创建custom action并创建尽可能多的or
条件。
can :my_update_action, Project do |project|
can?(:read, ModelX) || can?(:read, ModelY) || ...
end
答案 1 :(得分:1)
最后,我为能力类添加了这个相当不错的解决方案:
def multi_authorize!(*actions, message_hash)
message = nil
if message_hash.kind_of?(Hash) && message_hash.has_key?(:message)
message = message_hash[:message]
end
auth = false
actions.each do |act|
auth = auth || can?(act[0], act[1])
end
if !auth
message ||= unauthorized_message(actions[0][0], actions[0][1])
raise CanCan::AccessDenied.new(message, actions[0][0], actions[0][1])
end
end
包含控制器的帮助程序:
module CanCanAddition
def multi_authorize!(*args)
@_authorized = true
current_ability.multi_authorize!(*args)
end
end
if defined? ActionController::Base
ActionController::Base.class_eval do
include ApplicationHelper::CanCanAddition
end
end
我称之为:
def create
multi_authorize! [:create, Model1], [:authorize, Model2], :message => "You are not authorized to perform this action!"
# other code...
end
警告:由于能力类中的代码,您必须提供消息,否则最后一对授权将不会在*args
中传递。我需要一些时间来克服这个问题,但我认为解决方案的想法很合适。