首页 » 工作 » 方法 » 正文

嵌套集合模型 laravel-nestedset

发布者:站点默认
2020/12/28 浏览数(67) 分类:方法 嵌套集合模型 laravel-nestedset已关闭评论

介绍

laravel-nestedset(Nested Set Model)

安装

composer require kalnoy/nestedset

用法

// database/migrations/2020_08_10_155445_create_category_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCategoryTable extends Migration
{
  public function up()
  {
    Schema::create('category', function (Blueprint $table) {
      $table->id();
      $table->integer('parent_id')->nullable()->comment('所属分类');
      $table->string('name')->comment('级联名称');
      $table->string('sign')->comment('级联标识');
      $table->string('code')->nullable()->comment('枚举值');
      $table->integer('order')->comment('排序位置')->default(50);
      $table->boolean('enabled')->default(true)->comment('是否启用');
      $table->boolean('locked')->default(false)->comment('系统内置');
      $table->softDeletes();
      $table->timestamps();
      // $table->nestedSet(); // 默认的字段名为:_lft、_rgt、parent_id
      $table->unsignedInteger('_lft');
      $table->unsignedInteger('_rgt');
      $table->index('parent_id');
      $table->index(['sign', 'code']);
    });
  }
  public function down()
  {
    Schema::dropIfExists('category');
  }
}
// app/Cascade.php
namespace App;

use DateTimeInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Kalnoy\Nestedset\NodeTrait;

class Cascade extends Model
{
  use NodeTrait, SoftDeletes;

  public function getLftName()
  {
    return 'left';
  }

  public function getRgtName()
  {
    return 'right';
  }

  public function getParentIdName()
  {
    return 'parent';
  }
}

创建节点

Category::create($attributes);
$node = new Category($attributes);
$node->save(); // save为一个根节点(root)

编辑节点

// 设为根节点
$node->saveAsRoot(); // or: $node->makeRoot()->save();

// 添加子节点
$node->appendToNode($parent)->save();
$parent->appendNode($node);
$parent->children()->create($attributes);
$node->parent()->associate($parent)->save();

$node->parent_id = $parent->id;
$node->save();

// 添加父节点
$node->prependToNode($parent)->save();
$parent->prependNode($node);

// 插入节点(将$node添加为指定节点$neighbor的相邻节点,$neighbor必须存在,$node可以为新创建的节点,也可以为已存在的,如果$node为已存在的节点,它将移动到新的位置与$neighbor相邻,必要时它的父级将改变。)
# 显性save
$node->afterNode($neighbor)->save();
$node->beforeNode($neighbor)->save();
# 隐性 save
$node->insertAfterNode($neighbor);
$node->insertBeforeNode($neighbor);

//删除节点
$node->delete(); // 节点的所有后代将一并删除
Category::where('id', '=', $id)->delete(); // 禁止这样删除!!这将破坏树结构

祖先和后代

$node->ancestors; // 父节点
$node->descendants; // 子节点
$result = Category::ancestorsOf($id);
$result = Category::defaultOrder()->ancestorsOf($id); // 按层级排序
$result = Category::reversed()->ancestorsOf($id); // 倒序
$result = Category::ancestorsAndSelf($id);
$result = Category::descendantsOf($id);
$result = Category::descendantsAndSelf($id);
$bool = $node->isRoot(); // 是否为根节点
$bool = $node->isDescendantOf($parent); // 是否为其他节点的子节点
$node->isChildOf($other);
$node->isAncestorOf($other);
$node->isSiblingOf($other);
$node->isLeaf()
$bool = Category::isBroken(); // 检查树是否被破环
$data = Category::countErrors(); // 获取错误统计
Node::fixTree();

兄弟节点

有相同父节点的节点

$result = $node->getSiblings();
$result = $node->siblings()->get();
$result = $node->getNextSibling(); // 获取相邻的下一个兄弟节点
$result = $node->getNextSiblings(); // 获取后面的所有兄弟节点
$result = $node->nextSiblings()->get(); // 使用查询获得所有兄弟节点
$result = $node->getPrevSibling(); // 获取相邻的前一个兄弟节点
$result = $node->getPrevSiblings(); // 获取前面的所有兄弟节点
$result = $node->prevSiblings()->get(); // 使用查询获得所有兄弟节点

构建树

$nodes = Category::get()->toFlatTree(); // 一个扁平树
$root = Category::descendantsAndSelf($rootId)->toTree()->first();
$tree = Category::descendantsOf($rootId)->toTree($rootId);
// 将数组构建为树
$node = Category::create([
    'name' => 'Foo',

    'children' => [
        [
            'name' => 'Bar',

            'children' => [
                [ 'name' => 'Baz' ],
            ],
        ],
    ],
]);
点击返回顶部
  1. 留言
  2. 联系方式