Laravel firstOrCreate() 不适用于事件侦听器

Laravel firstOrCreate() not working with event listeners

提问人:andrysikova.petra 提问时间:8/13/2022 最后编辑:andrysikova.petra 更新时间:8/13/2022 访问量:314

问:

我有一个表“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”一样保存它,但该数字已经在数据库中。

我可能应该在事件侦听器以外的其他地方处理该数字。但是在哪里/如何?

PHP 事件 监听器 Laravel-9

评论

0赞 John Lobo 8/13/2022
使用验证规则唯一,这样可以避免存储此规则
0赞 andrysikova.petra 8/13/2022
好吧,我根本无法在保存之前从数字中删除空格,但要快得多。我可能会创建像 Phone::save_unique($phone) 这样的模型函数,并使用它来处理号码并检查重复项。无论如何,谢谢大家的帮助

答:

0赞 Aryan Hasanzadeh 8/13/2022 #1

嘿,您需要在迁移中设置数字列唯一属性

 $table->string('number')->unique();

在您的控制器中,在尝试管理数据之前,首先以如下所示的简单方法检查和验证数据,或者您可以使用正则表达式进行检查

'number' => 'required|numeric|min:8|max:11',

在变量中,你可以用它来代替dispatchesEventscreatingsaving

评论

0赞 andrysikova.petra 8/13/2022
谢谢。但我不想让验证阻止我。我希望如果有人尝试保存数据库中已有的数字,在他看来,此数字已保存,而没有显示任何验证错误。我使用“保存”是因为在创建和更新时都会调用它。如果我将“number”字段设置为唯一,则最终只会出现“完整性约束冲突”
0赞 Kamandlou 8/13/2022 #2

阅读此链接 https://laravel.com/docs/9.x/eloquent-mutators

并添加到您的迁移中。$table->string('number')->unique();

您可以使用这些规则来验证您的数字格式并确保它是唯一的'number' => 'required|numeric|min:8|max:11|unique:your_table_name'

评论

0赞 andrysikova.petra 8/13/2022
医 管 局!访问器和赋值器。这就是我要找的。谢谢!