paxha / laravel-adjacency-list
使用CTE的递归Laravel Eloquent关系
v2.1.2
2019-11-24 10:54 UTC
Requires
- php: ^7.2
- illuminate/database: ^6.0
- paxha/laravel-cte: ^2.0
Requires (Dev)
- laravel/homestead: ^9.0
- phpunit/phpunit: ^8.0
README
简介
此Laravel Eloquent扩展通过使用公用表表达式(CTE)提供递归关系。
支持Laravel 5.5.29及以上。
兼容性
- MySQL 8.0+
- MariaDB 10.2+
- PostgreSQL 9.4+
- SQLite 3.8.3+
- SQL Server 2008+
安装
composer require paxha/laravel-adjacency-list
用法
入门
考虑以下表架构用于分层数据
Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('parent_id')->nullable(); });
在模型中使用HasRecursiveRelationships
特性以处理递归关系
class User extends Model { use \Paxha\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships; }
默认情况下,特性期望一个名为parent_id
的父键。您可以通过覆盖getParentKeyName()
来自定义它
class User extends Model { use \Paxha\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships; public function getParentKeyName() { return 'parent_id'; } }
关系
特性提供各种关系
ancestors()
:模型的递归父级。ancestorsAndSelf()
:模型的递归父级和自身。children()
:模型的直接子级。childrenAndSelf()
:模型的直接子级和自身。descendants()
:模型的递归子级。descendantsAndSelf()
:模型的递归子级和自身。parent()
:模型的直接父级。parentAndSelf()
:模型的直接父级和自身。siblings()
:父级的其他子级。siblingsAndSelf()
:所有父级的子级。
$ancestors = User::find($id)->ancestors; $users = User::with('descendants')->get(); $users = User::whereHas('siblings', function ($query) { $query->where('name', '=', 'John'); })->get(); $total = User::find($id)->descendants()->count(); User::find($id)->descendants()->update(['active' => false]); User::find($id)->siblings()->delete();
树
特性提供tree()
查询作用域,以从根(s)开始获取所有模型
$tree = User::tree()->get();
过滤器
特性提供查询作用域,以根据模型在树中的位置进行过滤
hasChildren()
:具有子级的模型。hasParent()
:具有父级的模型。isLeaf()
:没有子级的模型。isRoot()
:没有父级的模型。
$noLeaves = User::hasChildren()->get(); $noRoots = User::hasParent()->get(); $leaves = User::isLeaf()->get(); $roots = User::isRoot()->get();
排序
特性提供查询作用域以对模型进行广度优先或深度优先排序
breadthFirst()
:先获取兄弟姐妹,再获取子级。depthFirst()
:先获取子级,再获取兄弟姐妹。
$tree = User::tree()->breadthFirst()->get(); $descendants = User::find($id)->descendants()->depthFirst()->get();
深度
祖先、后代和树查询的结果包括额外的depth
列。
它包含模型相对于查询父级的深度 相对 值。对于后代,深度为正,对于祖先,深度为负
$descendantsAndSelf = User::find($id)->descendantsAndSelf()->depthFirst()->get(); echo $descendantsAndSelf[0]->depth; // 0 echo $descendantsAndSelf[1]->depth; // 1 echo $descendantsAndSelf[2]->depth; // 2
您可以通过覆盖getDepthName()
来自定义列名
class User extends Model { use \Paxha\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships; public function getDepthName() { return 'depth'; } }
您可以使用whereDepth()
查询作用域通过模型的相对深度进行过滤
$descendants = User::find($id)->descendants()->whereDepth(2)->get(); $descendants = User::find($id)->descendants()->whereDepth('<', 3)->get();
路径
祖先、后代和树查询的结果包括额外的path
列。
它包含从查询父级到模型的唯一键的点分隔路径
$descendantsAndSelf = User::find(1)->descendantsAndSelf()->depthFirst()->get(); echo $descendantsAndSelf[0]->path; // 1 echo $descendantsAndSelf[1]->path; // 1.2 echo $descendantsAndSelf[2]->path; // 1.2.3
您可以通过覆盖相应的方法来自定义列名和分隔符
class User extends Model { use \Paxha\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships; public function getPathName() { return 'path'; } public function getPathSeparator() { return '.'; } }
贡献
有关详细信息,请参阅CONTRIBUTING和CODE_OF_CONDUCT。