提问人:andrysikova.petra 提问时间:8/13/2022 最后编辑:andrysikova.petra 更新时间:8/13/2022 访问量:314
Laravel firstOrCreate() 不适用于事件侦听器
Laravel firstOrCreate() not working with event listeners
问:
我有一个表“phones”,其中列“id”和“number”。我只需要存储唯一的电话号码。
我曾经这样做:
$phone = Phone::firstOrCreate(['number' => $phone['number']]);
它工作得很好。
现在我想保存不带空格的电话号码,但用空格显示它们以便更好地阅读。因此,我创建了两个事件侦听器,并将它们注册到Phone模型中,如下所示:
protected $dispatchesEvents = [
'saving' => \App\Events\Phone\PhoneSavingEvent::class,
'retrieved' => \App\Events\Phone\PhoneRetrievedEvent::class,
];
使用侦听器是这样定义的:
public function handle(PhoneSavingEvent $event)
{
$event->phone->number = preg_replace('/\s+/', '', $event->phone->number);
}
public function handle(PhoneRetrievedEvent $event)
{
$event->phone->number = wordwrap($event->phone->number, 3, ' ', true);
}
侦听器工作得很好。电话号码保存时不带空格,并用空格显示。但是函数 firstOrCreate() 现在将重复的电话号码保存到数据库中。
如何使用这两个侦听器再次保存唯一的电话号码?
谢谢
编辑:
如果我不使用而是使用此代码:$dispatchesEvents
protected static function booted()
{
static::saving(function ($phone) {
$phone->number = preg_replace('/\s+/', '', $phone->number);
});
}
firstOrCreate() 函数在尝试保存不带空格的数字(如“111222333”)时效果很好。它会在数据库中找到它,并且不会保存重复项。
但是,如果我尝试用空格保存数字(如“111 222 333”),firstOrCreate() 函数会像“111222333”一样保存它,但该数字已经在数据库中。
我可能应该在事件侦听器以外的其他地方处理该数字。但是在哪里/如何?
答:
嘿,您需要在迁移中设置数字列唯一属性
$table->string('number')->unique();
在您的控制器中,在尝试管理数据之前,首先以如下所示的简单方法检查和验证数据,或者您可以使用正则表达式进行检查
'number' => 'required|numeric|min:8|max:11',
在变量中,你可以用它来代替dispatchesEvents
creating
saving
评论
阅读此链接 https://laravel.com/docs/9.x/eloquent-mutators
并添加到您的迁移中。$table->string('number')->unique();
您可以使用这些规则来验证您的数字格式并确保它是唯一的'number' => 'required|numeric|min:8|max:11|unique:your_table_name'
评论