simpeldigitaal/tree-model

为 Eloquent 模型添加树结构。

dev-master 2018-12-11 20:53 UTC

This package is auto-updated.

Last update: 2024-09-12 10:49:57 UTC


README

用例

TreeModel,或称为嵌套子集,特别适用于存储和检索后续模型的完整树结构。它将在构建布局时防止许多查询,例如

  • 级别 1 - A
    • 级别 2 - AA
      • 级别 3 - AAA
      • 级别 3 - AAB
        • 级别 4 - AABA
        • ...
    • 级别 2 - AB
    • ...
  • ...

使用示例是页面或分类的菜单。

它还可以用于计算所有相关模型的总数,例如一个分类及其下级分类中的所有 products

$allCategories = $category->allChildren()->select(id);

$productCount = Product::whereHas('categories', function ($query) use ($allCategories, $category) {
    $query->whereIn('id', $allCategories);
    $query->orWhere('id', '=', $category->id);
})->count();

(注意:这只是一个伪代码,可能不会工作)

使用 TreeModel

此包具有两个核心功能:迁移助手和用于包含在 Eloquent 模型中的关系。迁移助手将通过 TreeModelServiceProvider 包含,但是关系也可以在没有它的情况下工作。

安装

使用 composer 需求此包。

composer require simpeldigitaal/tree-model

如果您不使用自动发现,请将 ServiceProvider 添加到 config/app.php 中的 providers 数组。

SimpelDigitaal\TreeModel\TreeModelServiceProvider::class

使用

在您的迁移中

up

    public function up()
    {
        Schema::table('menu', function (Blueprint $table) {
            ...
            $table->tree();
            ...
        });
    
    
        Schema::table('categories', function (Blueprint $table) {
            ...
            $table->treeWithId();
            ...
        });
    }

$table->tree($prefix = 'tree'); 生成存储树的必要字段(tree_starttree_end)。您能够更改默认前缀。

$table->treeWithId($name = 'parent_id', $prefix = 'tree'); 除了生成存储树的必要字段外,还会生成父子关系的字段。此字段可用于 HasManyBelongsTo 关系。

and down

    public function down()
    {
        Schema::table('menu', function (Blueprint $table) {
            ...
            $table->dropTree();
            ...
        });
            
        Schema::table('categories', function (Blueprint $table) {
            ...
            $table->dropTreeWithId();
            ...
        });

    }    

$table->dropTree($prefix = 'tree'); 删除树的字段。

$table->dropTreeWithId($name = 'parent_id', $prefix = 'tree'); 删除父子关系的字段...

在您的模型中

SimpelDigitaal\WebTree\Concerns\HasTree-trait 包含到您的 Eloquent 模型中。

在顶部

use SimpelDigitaal\WebTree\Concerns\HasTree;

在您的模型中

class Categories extends Model {

    use HasTree
    ...
    public function allChildren()
    {
        return $this->getTree();
    }

    public function childrenFromTree()
    {
        return $this->getSubsetTree('allChildren');
    }
    ...
}

getTree 将从数据库中检索所有子节点。 childrenFromTree 将检索下一级的子集,并为所有子节点播种它们自己的子集。它将使用并设置指定为第一个参数的关系。

构建树。

在存储新模型或更改现有模型后,您必须使用 $model->buildsTree() 重新构建树;

构建布局

示例

    $categories = Category::whereNull('parent_id')->with('allChildren')->get();
<ul>
    @foreach($categories as $category)
        <li>
            {{ $category->name }} | {{ $category->treeStart }} - {{ $category->treeEnd }}
            @include('categories._list', ['categories' => $category->childrenFromTree()])
        </li>
    @endforeach
</ul>

仅使用两个查询构建:第一个查询检索 $categories,第二个查询 eagerloading 关系 'allChildren'

享受

提示

添加约束

如果您想为您的树添加约束(例如 site_id),您可以使用 全局范围 设置此约束。

来源