phlak/laravel-pivot

此包已被废弃且不再维护。作者建议使用 fico7489/laravel-pivot 包。

此包为 BelongsToMany 关系中的 sync()、attach()、detach() 或 updateExistingPivot() 方法引入了新的 Eloquent 事件。

3.1.0 2023-01-25 15:59 UTC

README

此包为 BelongsToMany 关系中的 sync()、attach()、detach() 或 updateExistingPivot() 方法引入了新的 Eloquent 事件。

Laravel 问题

在 Laravel 中,当 BelongsToMany 关系(关联表)通过 sync()、attach()、detach() 或 updateExistingPivot() 方法更新时,不会分发事件,但此包可以帮助解决这个问题。

版本兼容性

Laravel 版本 包标签 支持 开发分支
>= 5.5.0 3.* yes master
< 5.5.0 - no -
  • 您仍然可以使用不活跃的分支为 laravel 5.4.x 或更早版本

安装

1.使用 composer 安装包

composer require phlak/laravel-pivot

此声明将使用 composer 安装您当前 laravel 版本可用的最高版本包。

2.在您的基模型或特定模型中使用 PHLAK\Laravel\Pivot\Traits\PivotEventTrait 特性。

use PHLAK\Laravel\Pivot\Traits\PivotEventTrait;
use Illuminate\Database\Eloquent\Model;

abstract class BaseModel extends Model
{
    use PivotEventTrait;
...

就这样,享受吧。

新的 Eloquent 事件

您可以在这里检查所有 Eloquent 事件:https://laravel.net.cn/docs/5.5/eloquent#events)

新的事件包括

pivotAttaching, pivotAttached
pivotDetaching, pivotDetached,
pivotUpdating, pivotUpdated

捕获事件的最佳方式是使用这些模型函数

public static function boot()
{
    parent::boot();

    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'
});

支持的关联

BelongsToManyMorphToMany

哪些事件被分发以及何时分发

四个 BelongsToMany 方法从这个包分发事件

attach()
分发一个 pivotAttaching 和一个 pivotAttached 事件。
即使添加了更多行,也只为所有行分发一个事件,但您可以在 $pivotIds 变量中看到所有更改的行 ID,以及具有属性的更改行 ID 在 $pivotIdsAttributes 变量中。

detach()
分发一个 pivotDetaching 和一个 pivotDetached 事件。
即使删除了更多行,也只为所有行分发一个事件,但您可以在 $pivotIds 变量中看到所有更改的行 ID。

updateExistingPivot()
分发一个 pivotUpdating 和一个 pivotUpdated 事件。
您可以使用 updateExistingPivot 仅更改关联表中的一行。

sync()
根据在关联表中添加的行数分发多个 pivotAttaching 和多个 pivotAttached 事件。如果没有附加任何内容,则不会分发这些事件。
分发一个 pivotDetaching 和一个 pivotDetached 事件,但您可以在 $pivotIds 变量中看到所有已删除的 ID。如果没有分离任何内容,则不会分发此事件。
例如,当调用 sync() 时,如果添加了两行并删除了两行,则将分发两个 pivotAttaching 和两个 pivotAttached 事件以及一个 pivotDetaching 和一个 pivotDetached 事件。
如果调用 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::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 分发一个事件。

使用 int 附加

运行此代码

$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']]

同步

对于sync()方法,为每个连接行(pivot row)触发事件。

运行此代码

$user = User::first();
$user->roles()->sync([1, 2]);

您将看到以下输出

pivotAttached
App\Models\User
roles
[1]
[1 => []]

pivotAttached
App\Models\User
roles
[2]
[2 => []]

解除附加

运行此代码

$user = User::first();
$user->roles()->detach([1, 2]);

您将看到以下输出

pivotDetached
App\Models\User
roles
[1, 2]

更新

运行此代码

$user = User::first();
$user->roles()->updateExistingPivot(1, ['attribute' => 'test']);

您将看到以下输出

pivotUpdated
App\Models\User
roles
[1]
[1 => ['attribute' => 'test']]

许可证

MIT

自由软件,太棒了!