【问题标题】:Laravel 5.8 syncing / attaching / detaching eventsLaravel 5.8 同步/附加/分离事件
【发布时间】:2019-08-18 21:59:36
【问题描述】:

Laravel 5.8 应该调度同步、附加和分离事件(https://laravel.com/docs/5.8/releases 搜索 Intermediate Table / Pivot Model Events 部分)。

更新:发布此问题后,发行说明已更新(更多信息:https://github.com/laravel/framework/issues/28050 - https://github.com/laravel/docs/pull/5096)。

我试过了,但是下面的代码抛出了异常:

调用未定义的方法 App\ProjectUser::syncing()

注意:由于 Laravel 5.8 应该调度同步事件,我不想使用外部包。

class User extends Model
{
    public function projects()
    {
        return $this->belongsToMany(\App\Project::class)->using(\App\ProjectUser::class);
    }
}

class Project extends Model
{
    public function users()
    {
        return $this->belongsToMany(\App\User::class)->using(\App\ProjectUser::class);
    }
}

class ProjectUser extends Pivot
{
    public static function boot()
    {
        parent::boot();

        static::syncing(function ($item) {
            dd('syncing event has been fired!');
        });
    }
}

// web.php
$project = \App\Project::first();
$project->users()->sync([1,2]);

我尝试将引导方法从ProjectUser 移动到UserProject,但我得到了同样的异常。

【问题讨论】:

  • 那里只有boot() 方法。
  • @Tpojka 你能说得更具体些吗?这是告诉 laravel 监听事件的常用方法(另一种方法是创建观察者)。
  • 抱歉,没有这样使用。我相当使用观察者,但没有使用通过引导方法。我只是搜索了文档,没有同步方法。

标签: php laravel laravel-5.8


【解决方案1】:

在 Laravel 5.8 上,当您使用 syncattachdetach 方法时,将为调用的操作触发适当的模型事件(创建、更新、保存...)。请注意,使用syncattachdetach 不会触发任何事件,如同步附加分离

更具体地说,为传递给sync 方法的每个元素触发的事件序列是:

  • 保存
  • 创建
  • 已创建
  • 已保存

为传递给attach 方法的每个元素触发的事件序列是:

  • 保存
  • 创建
  • 已创建
  • 已保存

为传递给detach 方法的每个元素触发的事件序列是:

  • 正在删除
  • 已删除

因此,如果您想观察同步操作,您实际上必须观察 来自枢轴模型的保存(或保存)事件(在本例中为 ProjectUser):

class ProjectUser extends Pivot
{
    public static function boot()
    {
        parent::boot();

        static::saving(function ($item)  {
            // this will die and dump on the first element passed to ->sync()
            dd($item);
        });
    }
}

一个工作示例https://github.com/danielefavi/laravel-issue-example

关于这个问题的更多信息https://github.com/laravel/framework/issues/28050

发行说明具有误导性,它们已被更改https://github.com/laravel/docs/pull/5096

【讨论】:

    【解决方案2】:

    如果在没有 id 的情况下调用分离方法(用于分离所有关系),则不会触发事件

    https://github.com/laravel/framework/pull/27571#issuecomment-493451259

    我尝试了很多不同的方法来解决这个需求,但是如果不使用外部包或覆盖许多方法是不可能的。

    我选择chelout/laravel-relationship-events包。

    它看起来干净且不稳定。并与 trait 一起使用。

    【讨论】:

    • 是的,你是对的,如果你想触发事件,分离方法需要 ID。分离所有元素并拥有事件的解决方案可以是:$project->users()->detach( User::all()->pluck('id') );
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2016-03-14
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 2016-05-22
    • 2019-09-07
    相关资源
    最近更新 更多