使用 `laravel-nestedset` 实现动态权限路由

laravel-nestedset 是一款基于嵌套集合模型(Nested Set Model)的用于实现有序树的 laravel 扩展包。

什么是嵌套集合模型?

嵌套集合或嵌套集合模型是一种在关系数据库表中高效存储分层数据的方法,理论基础为预排序遍历树算法(MPTT,Modified Preorder Tree Taversal)。

嵌套集合模型是根据树遍历对树中的每个节点进行数字编号,遍历会访问每个节点两次,按访问顺序分配数字编号,并在两次访问中都分配。这将为每个节点留下两个数字编号,它们作为节点的两个字段存储。这使得查询变得高效——可以通过比较这些数字编号来获得层级结构关系。但是更新数据将需要给节点重新分配数字,因此变得低效。尽管很复杂但是可以通过不使用整数而是使用有理数来提升写操作的效率。读高效,写低效

嵌套集合模型

其常用的应用场景为实现无限级分类。

使用laravel-nestedset

使用 laravel-nestedset 不仅可以实现无限级分类,同样可以实现动态权限路由。

比如这里我们要实现根据权限获取系统整个菜单树中的局部菜单树(也可以是整个菜单树,这个根据权限过滤后的结果):

	// 前置逻辑已经获取到根据权限筛选出的菜单路由id(menusIds)
	// 使用linkNodes方法可以为数据集合中的每个节点重新填充父子关系,即生成树结构
   $menus = Menu::whereIn('id', $menuIds)
   				->orWhereIn('parent_id', $menuIds)
   				->get()
   				->linkNodes();
   // 过滤其中的非root节点
   $user->menus = $menus->filter(function($item){
       return $item->isRoot();
   });

linkNodes方法为数据集合中的每个节点重新填充父子关系,其源码如下:

<?php

namespace Kalnoy\Nestedset;

use Illuminate\Database\Eloquent\Collection as BaseCollection;
use Illuminate\Database\Eloquent\Model;

class Collection extends BaseCollection
{
    /**
     * Fill `parent` and `children` relationships for every node in the collection.
     *
     * This will overwrite any previously set relations.
     *
     * @return $this
     */
    public function linkNodes()
    {
        if ($this->isEmpty()) return $this;

        $groupedNodes = $this->groupBy($this->first()->getParentIdName());

        /** @var NodeTrait|Model $node */
        foreach ($this->items as $node) {
            if ( ! $node->getParentId()) {
                $node->setRelation('parent', null);
            }

            $children = $groupedNodes->get($node->getKey(), [ ]);

            /** @var Model|NodeTrait $child */
            foreach ($children as $child) {
                $child->setRelation('parent', $node);
            }

            $node->setRelation('children', BaseCollection::make($children));
        }

        return $this;
    }

Ref:
Tree by Nodes #292
左右值无限级分类算法(预排序遍历树算法)
嵌套集合模型(Nested set model)介绍
kalnoy/nestedset

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seek-x2y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值