我需要限制用户只能通过'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
无济于事。
答案 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完成这项工作。当您输入索引操作时,实例变量将已初始化,但如果您无权查看任何列表,则该实例变量将为空。