cancancan authorize_resource 没有按预期工作
cancancan authorize_resource not working as expected
对于简单的 cancancan 授权,我遇到了意外行为。
ability.rb
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
user ||= User.new # guest user (not logged in)
if user.is_admin?
can :manage, :all
elsif user.is_standard?
can :manage, ServiceOrder, {user_id: user.id}
can :manage, ServiceOrderDetail, :service_order => { :user_id => user.id }
end
service_order.rb 控制器(部分显示)
class ServiceOrdersController < ApplicationController
authorize_resource
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
end
end
这不起作用,因为它让控制器显示任何 service_order 记录,而不仅仅是 current_user.
拥有的记录
唯一可行的方法是我手动授权控制器添加:
authorize! :show, @service_order
像这样:
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
authorize! :show, @service_order
end
这没有意义,因为 authorize_resource
应该这样做。
我的建议:使用 authorize_resource 而不是使用 load_and_authorize_resource,下面是您的控制器示例
只需确保您的 strong_parameters 声明:service_order_params
load_and_authorize_resource param_method: :service_order_params
发生的事情是 authorize_resource
在显示操作之前发生,并且由于 @service_order
尚未设置,它正在检查 class,并且用户确实可以显示 ServiceOrder
刚好受约束。
Adding authorize_resource will install a before_action callback that calls authorize!, passing the resource instance variable if it exists. If the instance variable isn't set (such as in the index action) it will pass in the class name. For example, if we have a ProductsController it will do this before each action.
authorize!(params[:action].to_sym, @product || Product)
按照 widjajayd 的建议,您需要做的是 load_and_authorize_resource
。或者(如果您不想使用 cancancan 默认加载操作)执行 before_filter
,在 authorize_resource
调用之前使用您的自定义方法手动加载资源。
对于简单的 cancancan 授权,我遇到了意外行为。
ability.rb
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
user ||= User.new # guest user (not logged in)
if user.is_admin?
can :manage, :all
elsif user.is_standard?
can :manage, ServiceOrder, {user_id: user.id}
can :manage, ServiceOrderDetail, :service_order => { :user_id => user.id }
end
service_order.rb 控制器(部分显示)
class ServiceOrdersController < ApplicationController
authorize_resource
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
end
end
这不起作用,因为它让控制器显示任何 service_order 记录,而不仅仅是 current_user.
拥有的记录唯一可行的方法是我手动授权控制器添加:
authorize! :show, @service_order
像这样:
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
authorize! :show, @service_order
end
这没有意义,因为 authorize_resource
应该这样做。
我的建议:使用 authorize_resource 而不是使用 load_and_authorize_resource,下面是您的控制器示例 只需确保您的 strong_parameters 声明:service_order_params
load_and_authorize_resource param_method: :service_order_params
发生的事情是 authorize_resource
在显示操作之前发生,并且由于 @service_order
尚未设置,它正在检查 class,并且用户确实可以显示 ServiceOrder
刚好受约束。
Adding authorize_resource will install a before_action callback that calls authorize!, passing the resource instance variable if it exists. If the instance variable isn't set (such as in the index action) it will pass in the class name. For example, if we have a ProductsController it will do this before each action.
authorize!(params[:action].to_sym, @product || Product)
按照 widjajayd 的建议,您需要做的是 load_and_authorize_resource
。或者(如果您不想使用 cancancan 默认加载操作)执行 before_filter
,在 authorize_resource
调用之前使用您的自定义方法手动加载资源。