nevadskiy / laravel-position
按指定顺序排列Laravel模型。
Requires
- php: ^7.2|^8.0|^8.2
- laravel/framework: ^7.0|^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- orchestra/testbench: ^5.0|^6.0|^7.0|^8.0|^9.0
- phpunit/phpunit: ^8.0|^9.0|^10.5
README
🔢 按指定顺序排列Laravel模型
✅ 要求
- Laravel
7.0或更高版本 - PHP
7.2或更高版本
🔌 安装
使用Composer安装此包
composer require nevadskiy/laravel-position
🔨 添加位置到模型
将HasPosition特性添加到需要位置的模型中
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Nevadskiy\Position\HasPosition; class Category extends Model { use HasPosition; }
您还需要使用迁移在模型的表中添加一个position列
Schema::create('categories', function (Blueprint $table) { $table->integer('position')->unsigned()->index(); });
就是这样!
📄 文档
工作原理
具有位置的模型有一个名为position的整数属性,它指示其在序列中的位置。此属性在插入时自动计算,并在查询操作中对模型进行排序时使用。
创建模型
position属性是一种数组索引,在创建新模型时自动插入。例如
$category = Category::create(); echo $category->position; // 0 $category = Category::create(); echo $category->position; // 1 $category = Category::create(); echo $category->position; // 2
起始位置
默认情况下,序列中的第一条记录被分配一个值为0的位置。如果您想指定一个自定义的数字开始计数模型,您可以在模型中重写getStartPosition方法
public function getStartPosition(): int { return 1; }
在这个例子中,第一条记录将被分配一个值为1的位置。
排序
默认情况下,新创建的模型被分配序列末尾的位置。
例如,如果您想在序列的开头创建模型,您可以在模型中重写getNextPosition方法
public function getNextPosition(): int { return $this->getStartPosition(); }
在这个例子中,每个新模型都将被分配起始位置,并将位于序列的开头。序列中其他模型的位置将自动更新
$first = Category::create(); echo $first->position; // 0 $second = Category::create(); echo $second->position; // 0 echo $first->position; // 1 (automatically updated) $third = Category::create(); echo $third->position; // 0 echo $second->position; // 1 (automatically updated) echo $first->position; // 2 (automatically updated again)
您还可以使用负位置。例如,-1位置表示模型将被定位在序列的末尾。它与Model::count() - 1几乎相同。这是默认行为。
删除模型
当模型被删除时,序列中其他记录的位置将自动更新。
查询模型
要选择按顺序排列的模型,您可以使用orderByPosition作用域。例如
Category::orderByPosition()->get();
查询模型时的自动排序
orderByPosition作用域默认情况下不会被应用,因为相应的SQL语句将被添加到所有查询中,即使它不是必需的。
建议在需要的地方手动添加作用域。
但是,如果您想为所有查询操作启用自动排序,您可以在模型中重写alwaysOrderByPosition方法,如下所示
public function alwaysOrderByPosition(): bool { return true; }
移动项目
更新
要将模型移动到序列中的任意位置,您只需更新其位置。例如
$category->update([ 'position' => 3 ]);
其他模型的位置也将自动重新计算。
移动
您还可以使用move方法,该方法设置新的位置值并立即更新模型。例如
$category->move(3);
如果您想将模型移动到序列的末尾,您可以使用负位置值。例如
$category->move(-1); // Move to the end
交换
swap方法交换两个模型的位置。例如
$category->swap($anotherCategory);
排列模型
还可以根据模型ID来排列模型。每个模型的位置将根据其在给定数组中ID的索引重新计算。您还可以提供一个起始位置作为第二个参数。例如
Category::arrangeByKeys([3, 5, 7]);
分组模型
位置分组特别适用于您希望在相同表格内的不同记录组中分别保持位置序列时。
要启用位置分组,您可以使用模型中的groupPositionBy方法指定一个或多个数据库列,这些列用作位置的分组标准。
public function groupPositionBy(): array { return [ 'category_id', ]; }
位置锁定
默认情况下,当您更改模型的位置或分组时,PositionObserver会自动通过执行额外的数据库查询来更新序列中其他模型的位置。如果您出于任何原因需要禁用此行为,可以这样做
use Nevadskiy\Position\PositionObserver; PositionObserver::lockFor(Category::class); $category->update(['position' => 1]); PositionObserver::unlockFor(Category::class);
📑 更新日志
有关最近更改的更多信息,请参阅更新日志。
☕ 贡献
有关更多信息,请参阅贡献指南。
🔓 安全性
如果您发现任何与安全相关的问题,请通过电子邮件与我联系,而不是使用问题跟踪器。
📜 许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证。
🛠️ 待办事项列表
- 支持来自不同组的模型使用
swap