代码之家  ›  专栏  ›  技术社区  ›  Carpela

当id不为空时允许访问cancan/cancancan

  •  1
  • Carpela  · 技术社区  · 8 年前

    我想出了一个残忍的方法。

    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
    


    额外信息:值得注意的是,这些并不是录制和电子邮件模型上唯一的控件,所以重要的是我可以添加额外的权限,而不是重置和负面表达。

    2 回复  |  直到 8 年前
        1
  •  5
  •   Community CDub    4 年前

    有两种方法可以实现这一点:

    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
    
        2
  •  0
  •   bradlis7    8 年前

    我有这个需求,这里有一个解决方案,可能快得多。你不必用 pluck ,并且没有理由将范围更改为数组,因为检查范围工作正常(我不确定这是否在库内部使用范围,但理想情况下会这样)。

    can :manage, [Recording, Email], :lead_id => (1..(2**31-1))
    

    我正在使用 cancancan .