genealabs / laravel-pivot-events
此包为 BelongsToMany 关系中的 sync()、attach()、detach() 或 updateExistingPivot() 方法引入了新的 Eloquent 事件。
Requires
- illuminate/database: ^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
Requires (Dev)
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^10.5
- symfony/thanks: ^1.0
README
此包为 BelongsToMany 和 MorphToMany 关系中的 sync()、attach()、detach() 或 updateExistingPivot() 方法引入了新的 Eloquent 事件。
此包是 fico7489/laravel-pivot 的分支,主要为了解决与 Laravel Telescope 和 Laravel 模型缓存 的兼容性问题。
赞助商
感谢以下赞助商的慷慨。请花一点时间了解他们
要求
- Laravel 8.0+
- PHP 7.3+
安装
1. 使用 composer 安装包: composer require "genealabs/laravel-pivot-events:*"
- 在您的基模型或特定模型中使用
GeneaLabs\LaravelPivotEvents\Traits\PivotEventTrait
特性。// ... use GeneaLabs\LaravelPivotEvents\Traits\PivotEventTrait; use Illuminate\Database\Eloquent\Model; abstract class BaseModel extends Model { use PivotEventTrait; // ... }
新 Eloquent 事件
您可以在这里查看所有 Eloquent 事件:https://laravel.net.cn/docs/5.8/eloquent#events)
新事件有
pivotSyncing
,pivotSynced
pivotAttaching
,pivotAttached
pivotDetaching
,pivotDetached
pivotUpdating
,pivotUpdated
捕捉事件的最简单方法是使用模型中 boot()
方法的函数
public static function boot() { parent::boot(); static::pivotSyncing(function ($model, $relationName) { // }); static::pivotSynced(function ($model, $relationName, $changes) { // }); static::pivotAttaching(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) { // }); static::pivotAttached(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) { // }); static::pivotDetaching(function ($model, $relationName, $pivotIds) { // }); static::pivotDetached(function ($model, $relationName, $pivotIds) { // }); static::pivotUpdating(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) { // }); static::pivotUpdated(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) { // }); static::updating(function ($model) { //this is how we catch standard eloquent events }); }
您还可以使用专用事件监听器来捕捉它们
\Event::listen('eloquent.*', function ($eventName, array $data) { echo $eventName; //e.g. 'eloquent.pivotAttached' });
支持的关系
BelongsToMany 和 MorphToMany
哪些事件会被触发以及它们何时会被触发
四个 BelongsToMany 方法从这个包触发事件
attach()
触发一个 pivotAttaching 和一个 pivotAttached 事件。
即使添加了更多行,也只为所有行触发一个事件,但在这种情况下,您可以在 $pivotIds 变量中看到所有更改的行 ID,以及在 $pivotIdsAttributes 变量中看到带有属性的更改行 ID。
detach()
触发一个 pivotDetaching 和一个 pivotDetached 事件。
即使删除了更多行,也只为所有行触发一个事件,但在这种情况下,您可以在 $pivotIds 变量中看到所有更改的行 ID。
updateExistingPivot()
触发一个 pivotUpdating 和一个 pivotUpdated 事件。
您只能使用 updateExistingPivot 更改枢纽表中的一行。
sync()
触发一个 pivotSyncing 和一个 pivotSynced 事件。
在同步过程中,是否为行添加/删除/更新只触发一个事件,但在这种情况下,您可以在 $changes 变量中看到所有已添加/删除/更新的行。
例如 sync 的工作原理: sync 首先断开所有关联,然后逐个添加或更新新条目。
用法
数据库中有三个表:users(id, name),roles(id, name),role_user(user_id, role_id)。我们有两个模型
class User extends Model
{
use PivotEventTrait;
// ...
public function roles()
{
return $this->belongsToMany(Role::class);
}
static::pivotSynced(function ($model, $relationName, $changes) {
echo 'pivotSynced';
echo get_class($model);
echo $relationName;
print_r($changes);
});
static::pivotAttached(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) {
echo 'pivotAttached';
echo get_class($model);
echo $relationName;
print_r($pivotIds);
print_r($pivotIdsAttributes);
});
static::pivotUpdated(function ($model, $relationName, $pivotIds, $pivotIdsAttributes) {
echo 'pivotUpdated';
echo get_class($model);
echo $relationName;
print_r($pivotIds);
print_r($pivotIdsAttributes);
});
static::pivotDetached(function ($model, $relationName, $pivotIds) {
echo 'pivotDetached';
echo get_class($model);
echo $relationName;
print_r($pivotIds);
});
// ...
}
class Role extends Model
{
// ...
}
附加
对于 attach() 或 detach(),为每个枢纽 ID 触发一个事件。
使用主键附加
运行此代码
$user = User::first(); $user->roles()->attach(1);
您将看到以下输出
pivotAttached
App\Models\User
roles
[1]
[1 => []]
使用数组附加
运行此代码
$user = User::first();
$user->roles()->attach([1]);
您将看到以下输出
pivotAttached
App\Models\User
roles
[1]
[1 => []]
使用模型附加
运行此代码
$user = User::first(); $user->roles()->attach(Role::first());
您将看到以下输出
pivotAttached
App\Models\User
roles
[1]
[1 => []]
使用集合附加
运行此代码
$user = User::first(); $user->roles()->attach(Role::get());
您将看到以下输出
pivotAttached
App\Models\User
roles
[1, 2]
[1 => [], 2 => []]
使用数组附加 (id => 属性)
运行此代码
$user = User::first();
$user->roles()->attach([1, 2 => ['attribute' => 'test']], ['attribute2' => 'test2']);
您将看到以下输出
pivotAttached
App\Models\User
roles
[1, 2]
[1 => [], 2 => ['attribute' => 'test', 'attribute2' => 'test2']]
同步
运行此代码
$user = User::first(); $user->roles()->attach([ 1 => ['pivot_attribut' => 1], 2 => ['pivot_attribut' => 0] ]); $user->roles()->sync([ 1 => ['pivot_attribut' => 0] 3 => ['pivot_attribut' => 1] ]);
您将看到以下输出
pivotSynced
App\Models\User
roles
[
"attached" => [
0 => 3
]
"detached" => [
1 => 2
]
"updated" => [
0 => 1
]
]
解除附加
运行此代码
$user = User::first();
$user->roles()->detach([1, 2]);
您将看到以下输出
pivotAttached
App\Models\User
roles
[1, 2]
更新
运行此代码
$user = User::first();
$user->roles()->updateExistingPivot(1, ['attribute' => 'test']);
您将看到以下输出
pivotUpdated
App\Models\User
roles
[1]
[1 => ['attribute' => 'test']]