Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby cancancan的多级授权_Ruby_Ruby On Rails 5_Cancancan - Fatal编程技术网

Ruby cancancan的多级授权

Ruby cancancan的多级授权,ruby,ruby-on-rails-5,cancancan,Ruby,Ruby On Rails 5,Cancancan,我面临着一个挑战。一个多级授权系统和一个朋友告诉我cancancan可以帮我 我看了一下文件,但没能弄明白。所以我会在这里解释。 我的目标是创建一个系统: 来自南方部门的用户“John”创建了Jane 用户Jane创建June和Paul 用户June和Paul创建了Bob、Nat和Emily 也 来自北方部门的用户彼得创建了丽塔 用户Rita创建Becca和Lisa 用户Becca和Lisa创建了Clara、Lory和Alexa 现在,每个用户只能看到自己制作的记录,或者来自低于但不高于

我面临着一个挑战。一个多级授权系统和一个朋友告诉我cancancan可以帮我

我看了一下文件,但没能弄明白。所以我会在这里解释。 我的目标是创建一个系统:

  • 来自南方部门的用户“John”创建了Jane
  • 用户Jane创建June和Paul
  • 用户June和Paul创建了Bob、Nat和Emily

  • 来自北方部门的用户彼得创建了丽塔
  • 用户Rita创建Becca和Lisa
  • 用户Becca和Lisa创建了Clara、Lory和Alexa
现在,每个用户只能看到自己制作的记录,或者来自低于但不高于或来自其他部门的用户的记录


如何从模型和所有内容开始?

首先,您需要在数据库级别跟踪此树。为此,您可以向
users
表添加一个
parent\u id
引用,该表将引用创建该特定用户的用户。对于不是由任何人创建的用户,此列将为空,否则将保留父用户的
id
。为了保证引用的完整性,我强烈建议使用外键

然后,您需要以正确遍历此树结构的方式定义您的CanCanCan能力。您可以将此示例作为参考,该示例源自:

我假设
User
模型有一个
substant\u of?
方法,该方法从当前用户向根用户遍历树,检查给定用户是否是资源创建者的父用户。可能的实现如下所示:

# app/models/user.rb

def descendant_of?(target_user)
  parent_id == target_user.id || parent&.descendant_of?(target_user)
end
根据用户树的特征,此建议的效率可能会很快变差,因为从所有者到根用户的所有用户都可能从数据库加载以执行这些检查。如果您开始面临这些问题,以下是一些值得探讨的想法:

  • 父ID
    列使用类似数组的类型来存储父ID的整个列表。我看到这个方案的主要缺点是,如果树中有更改,并且引用完整性约束丢失,那么它会增加一些开销(AFAIK,在这个场景中不可能添加外键)
  • 除了上述建议之外,还可以修改CanCanCan直接对数据库运行查询的能力,而不是在内存中进行检查(执行ruby代码)

  • 也许你可以澄清一下这个问题它是树之王HouthDeptUser1--user2--user3--user4 NorthDepUser1--user3--user3.1\user4--user4.1\user4.2就像你需要递归一样我非常非常感谢你。你给了我很多东西,我认为你已经把我指向了一个好的方向。我会研究并尝试你所有的建议。
    # app/models/user.rb
    
    def descendant_of?(target_user)
      parent_id == target_user.id || parent&.descendant_of?(target_user)
    end