codrasil/closurable

PHP Laravel 中任何层次数据的闭包关系数据库实现

v1.1.1 2020-05-07 09:12 UTC

This package is auto-updated.

Last update: 2024-09-07 19:26:55 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

PHP 中任何层次数据的闭包关系数据库实现。

要求

  • PHP: ^7.x
  • MySQL: 任何版本均可。

安装

此包最初是为 Laravel 构建的,但也可用于任何 PHP 项目。

在文档中了解更多关于集成的内容。

通过 composer

composer require codrasil/closurable

发布配置

将包的服务提供者传递给 artisan 命令

php artisan vendor:publish --provider="Codrasil\Closurable\NestableServiceProvider"

设置

生成迁移文件

首先,运行控制台命令以生成嵌套迁移表。

格式

make:closurable [options] [--] <reference>

示例

我们将使用 users 模型来生成用户的嵌套关系。

php artisan make:closurable users

命令接受一个参数,即 引用表。这将是要“闭包”的表。

它将生成一个名为 userstree 的表,该表预先填充了必要的列。

生成的文件应如下所示

Schema::create('userstree', function (Blueprint $table) {
    $table->unsignedBigInteger('ancestor_id')->index();
    $table->unsignedBigInteger('descendant_id')->index();
    $table->unsignedBigInteger('depth')->index()->default(0);
    $table->unsignedBigInteger('root')->index()->default(0);
    $table->unique(['ancestor_id', 'descendant_id']);
    $table->index(['ancestor_id', 'descendant_id', 'depth']);
    $table->index(['descendant_id', 'depth']);
    $table->index(['depth', 'root']);
    $table->foreign('ancestor_id')
          ->references('id')
          ->on('users')
          ->onDelete('cascade')
          ->onUpdate('cascade');
    $table->foreign('descendant_id')
          ->references('id')
          ->on('users')
          ->onDelete('cascade')
          ->onUpdate('cascade');
});

注意 在运行命令之前,您应该自己生成 引用表 的迁移文件(在上面的示例中,您应该自己生成 users 表的迁移文件)。

注意 要更改闭包表的表名,请传递选项 --table--create

php artisan make:closurable users --table=familytree

运行 php artisan make:closurable --help 获取有关配置命令的更多信息。

模型使用

接下来,在要嵌套闭包的模型上使用两种选项之一。

根据我们上面的示例,User 模型应实现以下之一:

  • 特质,Closurable

    use Codrasil\Closurable\Closurable;
    
    class User extends Authenticatable
    {
        use Closurable;
    }
    

  • 通过扩展抽象类 Codrasil\Closurable\Model,而不是默认的 Illuminate Model 类

    use Codrasil\Closurable\Model;
    
    class User extends Model
    {
       // Of course, you will need to reimplement the Authenticatable traits
       // to the User model if you ARE going to nest the User model.
    }
    

用法

保存分支节点

假设我们在 users 表上具有以下数据

我们需要以下关系

要保存上述描述的关系,我们需要使用 User 模型中的 closurables() 来访问 attach(Model $model) 方法。

$parent = User::find(1); // Jones, Sr.
$junior = User::find(2); // Indy
$parent->closurables()->attach($junior);

...

$child = User::find(3); // Susie
$parent->closurables()->attach($child);

...
$child = User::find(4); // Jones III
$junior->closurables()->attach($child);

该关系将保存到 familytree 表中,如下所示

可视化表示

显示根节点
  • 要显示没有父级的资源,请使用 roots 范围

    $roots = MyModel::roots()->get();

查询相邻关系

默认情况下,排序通过在 参考表 中找到的 sort 列来处理。如果 sort 列不可用,则默认为 id$this->getKeyName() 将返回的内容。

  • 兄弟姐妹

    要检索子级的所有兄弟姐妹,请使用 siblings() 方法

    $child = MyModel::find(2);
    $siblings = $child->siblings(); // or $child->siblings
    • 一个用于检查空值的辅助方法 ->hasSiblings() 可用。
    • 一个访问器方法 getSiblingsAttribute 可用。
  • 下一个兄弟姐妹

    要在 $user->children 中显示下一个兄弟姐妹,请使用 next() 方法

    $firstChild = MyModel::find(2);
    $secondChild = $firstChild->next(); // or $firstChild->next
    • 一个用于检查空值的辅助方法 ->hasNext() 可用。
    • 一个访问器方法 getNextAttribute 可用。
  • 上一个兄弟姐妹

    要显示上一个兄弟姐妹,请使用 previous() 方法

    $secondChild = MyModel::find(3);
    $firstChild = $secondChild->previous(); // or $secondChild->previous
    • 一个用于检查空值的辅助方法 ->hasPrevious() 可用。
    • 一个访问器方法 getPreviousAttribute 可用。

查询线性关系

  • 父级

    要检索子级的直接父级,请使用 parent() 方法

    $child = MyModel::find(2);
    $parent = $child->parent(); // or $child->parent
    • 一个用于检查空值的辅助方法 ->hasParent() 可用。
    • 提供了一个访问器方法 getParentAttribute
  • 子节点

    要显示特定资源的子节点,请使用 children() 方法

    $user = User::find(1);
    {{-- in a blade file --}}
    
    @foreach ($user->children() as $child)
      {{ $child->name }}
    @endforeach
    
    {{-- use @dd($user->children) to see entire collection --}}
    • 提供了一个用于检查空性的辅助方法 ->hasChildren()
    • 提供了一个访问器方法 getChildrenAttribute
  • 祖先

    要获取子节点的所有父节点(以及子节点的父节点的父节点等),请使用 ancestors() 方法

    $child = MyModel::find(4);
    $ancestors = $child->ancestors();
    // will output the parent([of the parent]*n) + the child.
    // dd($ancestors) to inspect actual data.
    • 提供了一个用于检查空性的辅助方法 ->hasAncestors()
    • 提供了一个访问器方法 getAncestorsAttribute
  • 后代

    要获取父节点的所有子节点(以及父节点子节点的子节点等),请使用 descendants() 方法

    $parent = MyModel::find(2);
    $descendants = $parent->descendants();
    // will output the children([of the children]*n) + the parent.
    // dd($descendants) to inspect actual data.
    • 提供了一个用于检查空性的辅助方法 ->hasDescendants()
    • 提供了一个访问器方法 getDescendantsAttribute

有关 adjacentlineal 关系的更多使用案例,请查看文档中的 “关系” 部分。

文档 & 示例

要了解更多关于 API 的信息,请访问 docs 文件夹。

更多示例实现,请查看 docs/examples 文件夹。示例页面包含各种用例,例如 评论系统动物王国的分类排名家谱 等。

许可证

此库是开源软件,采用 MIT 许可协议