Laravel 6 - pivot table sync - 仅当附加用户是新用户时才触发创建的事件

Larave 6 - pivot table sync - fire created event only if the attached user is new

我有以下代码:

$clinic->users()->sync($sync);

将转到此 class(同步正常):

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class ClinicUser extends Pivot
{
    protected $table = 'clinic_user';

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

        static::created(function($item) {

            $user   = \App\User::find($item->users_id);
            $clinic = \App\Models\Clinic::find($item->clinics_id);

            if($user->userData->notification_email == 1)
                \Mail::to($user->email)->send(new \App\Mail\ClinicManagerAdded(
                    $user,
                    $clinic));

            if($user->userData->notification_app == 1)
                \App\Notification::create([
                    'title'   => "message",
                    'body'    => "message",
                    'user_id' => $user->id,
                ]);

        });
    }
}

是否可以只对新用户触发创建的方法(没有分离)?

如果有人有类似的问题,我已经设法通过创建静态变量来解决这个问题,并在 deleted 事件中填充这个变量,如下所示:

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class ClinicUser extends Pivot
{
    protected $table = 'clinic_user';

    static $ids = [];

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

        static::deleted(function($item){
           self::$ids[] = $item->users_id;
        });

        static::created(function($item){

            if(!\in_array($item->users_id, self::$ids)){
                $user   = \App\User::find($item->users_id);
                $clinic = \App\Models\Clinic::find($item->clinics_id);

                if($user->userData->notification_email == 1)
                    \Mail::to($user->email)->send(new \App\Mail\ClinicManagerAdded(
                        $user,
                        $clinic));

                if($user->userData->notification_app == 1)
                    \App\Notification::create([
                        'title'   => "new message",
                        'body'    => "<p>body</p>",
                        'user_id' => $user->id,
                    ]);
            }


        });
    }
}

我的建议不是那么可靠,事实上你需要做

$clinic->users()->detach($sync->pluck('id'));
$clinic->users()->sync($sync);

每一次,你都需要记住它(所以不太健壮)。

我觉得建议你做的是这样的:

  1. 删除模型中的通知
  2. 为这个操作创建一个服务,我们称它为NotyfyUsersNewClinicService(也许你会找到一个更好的名字):
<?php

namespace App;
use ...;

class NotyfyUsersNewClinicService{

    public __constructor(){}

    public updateUsers(Clinic& $clinic, Collection& $newUsers){
       $clinic->users->diff($newUsers)->each(function(User $users){
           $user->userData->notification_email = true;
           \Mail::to($user->email)->send(new \App\Mail\ClinicManagerAdded(
                    $user,
                    $clinic));
       });
       $clinic->users()->sync($sync);
    }
}
  1. 那么你只需要使用这个:

    (new NotyfyUsersNewClinicService())->updateUsers($clinic, $users);

注意:如果您将电子邮件移至作业并使用 queue:work

发送则更好