Home > Net >  Laravel firstOrCreate() not working with event listeners
Laravel firstOrCreate() not working with event listeners

Time:08-13

I have a table "phones" with columns "id" and "number". I need to store only unique phone numbers.

I used to do this:

$phone = Phone::firstOrCreate(['number' => $phone['number']]);

And it worked just fine.

Now I want to save phone numbers without spaces, but show them with spaces for better reading. So I created two event listeners and registered them in Phone model like this:

protected $dispatchesEvents = [
    'saving' => \App\Events\Phone\PhoneSavingEvent::class,
    'retrieved' => \App\Events\Phone\PhoneRetrievedEvent::class,
];

With listeners defines like this:

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);
}

Listeners works just fine. Phone numbers are saved without spaces and displayed with spaces. But function firstOrCreate() now saves duplicate phone numbers to database.

How can I save unique phone numbers again with these two listeners?

Thank you

EDIT:

If I don't use $dispatchesEvents but use this code instead:

protected static function booted()
{
    static::saving(function ($phone) {
        $phone->number = preg_replace('/\s /', '', $phone->number);
    });
}

The firstOrCreate() function works well, when trying to save number without spaces (like "111222333"). It will find that in database and won't save duplicate.

But if I try to save number with spaces (like "111 222 333") the firstOrCreate() function save it like "111222333", but that number is already in database.

I probably should treat the number somewhere else than in event listener. But where/how?

CodePudding user response:

Read this link https://laravel.com/docs/9.x/eloquent-mutators

And add $table->string('number')->unique(); to your migration.

You can use these rules to validate your number format and make sure that it is unique 'number' => 'required|numeric|min:8|max:11|unique:your_table_name'

CodePudding user response:

hey you need to set your number column unique attribute in you migration

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

in your controller before try to manage data check and validate data first the simple way like this below or you can check with regex to

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

and in your dispatchesEvents variable you can use creating instead of saving

  • Related