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);
每一次,你都需要记住它(所以不太健壮)。
我觉得建议你做的是这样的:
- 删除模型中的通知
- 为这个操作创建一个服务,我们称它为
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);
}
}
那么你只需要使用这个:
(new NotyfyUsersNewClinicService())->updateUsers($clinic, $users);
注意:如果您将电子邮件移至作业并使用 queue:work
发送则更好
我有以下代码:
$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);
每一次,你都需要记住它(所以不太健壮)。
我觉得建议你做的是这样的:
- 删除模型中的通知
- 为这个操作创建一个服务,我们称它为
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);
}
}
那么你只需要使用这个:
(new NotyfyUsersNewClinicService())->updateUsers($clinic, $users);
注意:如果您将电子邮件移至作业并使用 queue:work