雄辩的连接/分离/同步会触发任何事件?

Mih*_*iță 17 php laravel eloquent

我有一个laravel项目,我需要在保存模型并附加一些数据后立即进行一些计算.

调用attach(或detach/sync)后是否有任何事件在laravel中触发?

Jar*_*zyk 26

不,Eloquent中没有关系事件.但你可以轻松地自己做(给出例如Ticket belongsToMany Component关系):

// Ticket model
use App\Events\Relations\Attached;
use App\Events\Relations\Detached;
use App\Events\Relations\Syncing;
// ...

public function syncComponents($ids, $detaching = true)
{
    static::$dispatcher->fire(new Syncing($this, $ids, $detaching));

    $result = $this->components()->sync($ids, $detaching);

    if ($detached = $result['detached'])
    {
        static::$dispatcher->fire(new Detached($this, $detached));
    }

    if ($attached = $result['attached'])
    {
        static::$dispatcher->fire(new Attached($this, $attached));
    }
}
Run Code Online (Sandbox Code Playgroud)

事件对象就像这样简单:

<?php namespace App\Events\Relations;

use Illuminate\Database\Eloquent\Model;

class Attached {

    protected $parent;
    protected $related;

    public function __construct(Model $parent, array $related)
    {
        $this->parent    = $parent;
        $this->related   = $related;
    }

    public function getParent()
    {
        return $this->parent;
    }

    public function getRelated()
    {
        return $this->related;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后一个基本的听众作为一个明智的例子:

    // eg. AppServiceProvider::boot()
    $this->app['events']->listen('App\Events\Relations\Detached', function ($event) {
        echo PHP_EOL.'detached: '.join(',',$event->getRelated());
    });
    $this->app['events']->listen('App\Events\Relations\Attached', function ($event) {
        echo PHP_EOL.'attached: '.join(',',$event->getRelated());
    });
Run Code Online (Sandbox Code Playgroud)

和用法:

$ php artisan tinker

>>> $t = Ticket::find(1);
=> <App\Models\Ticket>

>>> $t->syncComponents([1,3]);

detached: 4
attached: 1,3
=> null
Run Code Online (Sandbox Code Playgroud)

当然,你可以在不创建Event对象的情况下完成它,但这种方式更方便,更灵活,更简单.


fic*_*489 9

解决问题的步骤:

  1. 创建自定义BelongsToMany关系
  2. 在BelongsToMany中,自定义关系覆盖attach,detach,sync和updateExistingPivot方法
  3. 在overriden方法中调度所需的事件.
  4. 覆盖Model中的belongsToMany()方法并返回自定义关系而不是默认关系

就是这样.我创建了已经这样做的包:https://github.com/fico7489/laravel-pivot


小智 7

Laravel 5.8 现在在 ->attach() 上触发事件

查看:https : //laravel.com/docs/5.8/releases

并搜索:中间表/枢轴模型事件

https://laracasts.com/discuss/channels/eloquent/eloquent-attach-which-event-is-fired?page=1


小智 6

更新:

从 Laravel 5.8 开始,Pivot 模型事件像普通模型一样调度。

https://laravel.com/docs/5.8/releases#laravel-5.8

您只需添加using(PivotModel::class)到您的关系中,事件就会在 PivotModel 上运行。 Attach($id)将调度Created和Creating

Detach($id)将发送“删除”和“已删除”,

Sync($ids)也会调度所需的事件 [已创建、正在创建、正在删除、已删除]

dispatch()到目前为止,只有没有 id 才不会发送任何事件。