为什么不能尊重我的规则?

时间:2013-03-31 22:26:03

标签: ruby-on-rails-3 cancan

我需要限制用户只能通过'supplier_id'访问他们的送货清单项目。我知道我可以使用'accessible_by'来添加'where'子句。但是如果我忘记将accessible_by范围添加到我的查询中,则在以下控制器的操作索引中,用户可以读取任何列表。

class SupplierShippingListsController < ApplicationController

    load_and_authorize_resource
    def index
        @shipping_lists = SupplierShippingList.where(:supplier_id => params[:supplier_id])
        authorize! :read, SupplierShippingList
    end

end

我首先定义了这个规则,跳过实例将根据我的哈希检查,但它没有,好像:supplier_id是没有意义的。

can :read, SupplierShippingList, :supplier_id => user.company_id

所以我尝试了一个带有随机值的块,使其无法通过授权,但用户仍然可以访问该操作。

can :read, SupplierShippingList do |list|
    list.supplier_id == 17
end

是否有一些隐藏的东西要设置?

修改

我也试过

authorize! :read, @shipping_lists

无济于事。

2 个答案:

答案 0 :(得分:1)

由于您使用的是load_and_authorize_resource,因此您无需执行任何操作。在您的索引操作中,如果您使用supplier_shipping_lists,它应该找到与用户公司对应的所有can :read, SupplierShippingList, :supplier_id => user.company_id。如果这不起作用,您是否有任何其他规则适用于SupplierShippingList

答案 1 :(得分:1)

索引操作将忽略该块,因此您的第二个示例将无效。对于像这样的相对简单的能力,你最好的选择是使用像你的第一个例子那样的条件哈希。但load_and_authorize_resource会自动为您加载@supplier_shipping_lists。您显示的索引操作将覆盖该变量,并使“加载和授权资源”的“加载”部分变得毫无意义。您应该删除索引操作并让CanCan为您执行加载。如果不覆盖实例变量,只要使用条件哈希值,就应该看到预期的结果。

此外,您也无需手动呼叫authorize!。这是load_and_authorize_resource的'授权'部分。你需要让CanCan完成这项工作。当您输入索引操作时,实例变量将已初始化,但如果您无权查看任何列表,则该实例变量将为空。