当 id 不为零时允许访问 cancan / cancancan
Allowing access cancan / cancancan when id is not nil
我正在尝试使用 cancan 授予存在关联的访问权限。
它需要同时处理对象属性和 accessible_by 选择(所以我不能使用块,除非有人告诉我如何在我这样做时绕过错误)。
我想出了一个残酷的黑客。
lead.rb
has_many :recordings
has_many :emails
ability.rb
can :manage, Lead
can :manage, Recording, :lead_id => (1..Lead.pluck(:id).max).to_a
can :manage, Email, :lead_id => (1..Lead.pluck(:id).max).to_a
我的意思是lead_id不为空...
有什么方法可以做到这一点而不必每次都创建 100,000 项数组?
额外信息:值得注意的是,这些并不是录音和电子邮件模型上唯一的控件,因此我可以添加额外的权限而不是重置并消极地表达它们,这一点很重要。
有两种方法可以实现:
1。能力的组合哈希
这是 recommended approach。 使用它,除非你有充分的理由不这样做。
这里的想法是combine一个cannot
能力,结合can
:
can :manage, Recording
cannot :manage, Recording, lead_id: nil
注意这里的order is important,这样规则覆盖是正确的。
2。能力方块
通过defining the ability with a block,您可以形成更复杂的查询。
一个简单的实现如下:
can :manage, Recording do |recording|
!recording.lead_id.nil?
end
但是,为了将此能力与其他能力结合起来,您还必须在获取记录时specify the SQL conditions。这个额外的 SQL 控制 load_resource
操作,例如 index
:
can :manage, Recording, ["lead_id IS NOT NULL"] do |recording|
!recording.lead_id.nil?
end
为了让这个逻辑保持干爽,您还可以考虑在一个块中定义您的权限,例如:
[Recording, Email].each do |model|
can :manage, model
cannot :manage, model, lead_id: nil
end
我有这个需求,这里有一个可能更快的解决方案。您不必使用 pluck
访问数据库,也没有理由将范围更改为数组,因为检查范围工作正常(我不确定这是否在库内部使用范围,但理想情况下它会)。
can :manage, [Recording, Email], :lead_id => (1..(2**31-1))
我正在使用 cancancan
。
我正在尝试使用 cancan 授予存在关联的访问权限。
它需要同时处理对象属性和 accessible_by 选择(所以我不能使用块,除非有人告诉我如何在我这样做时绕过错误)。
我想出了一个残酷的黑客。
lead.rb
has_many :recordings
has_many :emails
ability.rb
can :manage, Lead
can :manage, Recording, :lead_id => (1..Lead.pluck(:id).max).to_a
can :manage, Email, :lead_id => (1..Lead.pluck(:id).max).to_a
我的意思是lead_id不为空...
有什么方法可以做到这一点而不必每次都创建 100,000 项数组?
额外信息:值得注意的是,这些并不是录音和电子邮件模型上唯一的控件,因此我可以添加额外的权限而不是重置并消极地表达它们,这一点很重要。
有两种方法可以实现:
1。能力的组合哈希
这是 recommended approach。 使用它,除非你有充分的理由不这样做。
这里的想法是combine一个cannot
能力,结合can
:
can :manage, Recording
cannot :manage, Recording, lead_id: nil
注意这里的order is important,这样规则覆盖是正确的。
2。能力方块
通过defining the ability with a block,您可以形成更复杂的查询。
一个简单的实现如下:
can :manage, Recording do |recording|
!recording.lead_id.nil?
end
但是,为了将此能力与其他能力结合起来,您还必须在获取记录时specify the SQL conditions。这个额外的 SQL 控制 load_resource
操作,例如 index
:
can :manage, Recording, ["lead_id IS NOT NULL"] do |recording|
!recording.lead_id.nil?
end
为了让这个逻辑保持干爽,您还可以考虑在一个块中定义您的权限,例如:
[Recording, Email].each do |model|
can :manage, model
cannot :manage, model, lead_id: nil
end
我有这个需求,这里有一个可能更快的解决方案。您不必使用 pluck
访问数据库,也没有理由将范围更改为数组,因为检查范围工作正常(我不确定这是否在库内部使用范围,但理想情况下它会)。
can :manage, [Recording, Email], :lead_id => (1..(2**31-1))
我正在使用 cancancan
。