Aug*_*tos 4 ruby-on-rails cancan cancancan
我收到一个简单的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
Run Code Online (Sandbox Code Playgroud)
service_order.rb控制器(部分显示)
class ServiceOrdersController < ApplicationController
authorize_resource
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
end
end
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为它让控制器显示任何service_order记录,而不仅仅是current_user拥有的记录.
这种方法的唯一方法是,如果我手动授权控制器添加:
authorize! :show, @service_order
Run Code Online (Sandbox Code Playgroud)
像这样:
def show
@service_order = ServiceOrder.includes(:service_order_details).find(params[:id])
authorize! :show, @service_order
end
Run Code Online (Sandbox Code Playgroud)
这是没有意义的,因为authorize_resource应该这样做.
发生的事情是在authorize_resourceshow动作之前发生的事情,并且由于@service_order尚未设置,它正在检查类,并且用户确实有权显示ServiceOrder刚刚受限制.
添加authorize_resource将安装一个调用authorize!的before_action回调,传递资源实例变量(如果存在).如果未设置实例变量(例如在索引操作中),则它将传入类名.例如,如果我们有一个ProductsController,它将在每个动作之前执行此操作.
授权!(params [:action] .to_sym,@ product || Product)
你需要做的是load_and_authorize_resource按照widjajayd的建议.或者(如果您不想使用cancancan默认加载操作)请before_filter在authorize_resource调用之前使用自定义方法手动加载资源.
| 归档时间: |
|
| 查看次数: |
1054 次 |
| 最近记录: |