Search code examples
laravellaravel-8laravel-validation

Laravel 8 validate unique through columns and rows on create and update


I have got 3 columns in my table email_1, email_2, email_3. How to avoid duplicates between the rows while create and update?

For the update method, I can validate by columns like this:

public function rules()
{
    /** OTHER VALIDATION RULES */

    'email_1' => [
    'required',
    'email',
    'unique:users,email_1,' . $this->id,
    ],
    'email_2' => [
    'required',
    'email',
    'unique:users,email_2,' . $this->id,
    ],
    'email_3' => [
    'required',
    'email',
    'unique:users,email_3,' . $this->id,
    ]
    /** OTHER VALIDATION RULES */
}

The problem is avoiding using the same email address on the three input fields of my form?


Solution

  • Method 1

    The easiest way is to use the different validation rule. Something like this:

    'email_1' => [
      'required',
      'email',
      'different:email_2'
      'different:email_3',
      'unique:users,email,' . $this->id,
    ],
    'email_2' => [
      'required',
      'email',
      'different:email_1'
      'different:email_3',
      'unique:users,email_2,' . $this->id,
    ],
    'email_3' => [
      'required',
      'email',
      'different:email_1'
      'different:email_2',
      'unique:users,email_3,' . $this->id,
    ],
    

    Method 2

    I see you're validating within a Request class, which is great because you can make use of After Hooks.

    public function withValidator($validator)
    {
        $emails = [Request['email_1'], Request['email_2'], Request['email_3']];
        $validator->after(function ($validator) use ($emails) {
            if (count($emails) == count(array_unique($emails))) {
                // Add error to message bag.
                $validator->errors()->add('key', 'message');
            }
        });
    }
    

    The above example uses array_unique(), which will remove duplicates. Comparing length of original vs length of deduplicated one will show if duplicates are present.