Search code examples
phplaravellaravel-validation

How to make Laravel unique validation work on an input array?


UpdateEntityRequest.php:

'phones'          => 'sometimes|nullable|array',
'phones.*.id'     => 'sometimes|required|integer|distinct|exists:entity_phones,id,entity_id,'.$this->id,
'phones.*.number' => 'required|alpha_num|max:255|distinct|unique:entity_phones,number,'.$this->id.',entity_id',

entity_phones table:

id, number, entity_id.
unique constraint: (number, entity_id)

EntityRepository.php:

foreach ($attributes['phones'] as $phone) {
    if (isset($phone['id'])) {
        $entity->phones()->updateOrCreate([
            'id'         => $phone['id'],
            'entity_id'  => $entity->id
        ], $phone);
    } else {
        $entity->phones()->create($phone);
    }
}

My entity can have more than phone associated, but not a repeated number. My intention is to check the unique (entity_id, number) in the UpdateEntityRequest.php so:

  • If the phone object comes without an id, it should check that the combination of number, entity_id doesn't exists. But the number can exist with other entity_id.
  • If the request comes with an id, it should check that the combination of number, entity_id doesn't exists only in other ids, but ignore the given id.

I'm having trouble witht the Laravel Unique rule validating only when i want it to make the validation. Any ideas how could I make this solution would be appreciated.


Solution

  • I ended up doing this:

    $phoneIds = $this->input('phones.*.id');
    
    'phones.*.number' =>
                        [
                            'required_with:phones',
                            'alpha_num',
                            'max:255',
                            'distinct',
                            Rule::unique('entity_phones', 'number')
                            ->where('entity_id', $this->id)
                            ->where(function ($query) use ($phoneIds) {
                                return $query->where('id', '!=', array_shift($phoneIds));
                            })
                        ],