'Laravel check for unique rule without itself in update

I am having my validation rules for unique in the update section.

In inserting or adding the unique rule is 'Email' => array('unique:driver_details'), and it will check for the unique coloumn.

But this fails for the update section. While updating it satisfies the other rules and in the unique of email it is checking itself for the unique coloumn and it fails but seeing its own field.

So, how can i check for the unique except its own value in the database ?



Solution 1:[1]

This forces to ignore specific id:

'email' => 'unique:table,email_column_to_check,id_to_ignore'

replace segments table, email_column_to_check, id_to_ignore in above example

You could check it here http://laravel.com/docs/4.2/validation#rule-unique

Solution 2:[2]

For those using Laravel 5 and Form Requests, you may get the id of the model of the Route-Model Binding directly as a property of the Form Request as $this->name_of_the_model->id and then use it to ignore it from the unique rule.

For instance, if you wanted to have unique emails, but also allow an administrator to edit users, you could do:

Route:

Route::patch('users/{user}', 'UserController@update');

Controller:

public function update(UserRequest $request, User $user) 
{
    // ...
}

Form Request:

class UserRequest extends FormRequest
{
    // ...
    public function rules()
    {
        return [
            'name' => 'required|string',
            'email' => [
                'required',
                'email',
                Rule::unique('users')->ignore($this->user()->id, 'id')
            ],
            //...
        ];
    }
    //...
}

Please note that we are ignoring the user that is being edited, which in this case could be different than the authenticated user.

Solution 3:[3]

$request->validate([
    'email' => 'unique:table_name,email,' . $user->id
]);

Solution 4:[4]

I am using Laravel 5.2

if your primary key is named 'id' table name is users_table and I want to update user_name so I do it this way

'user_name'  =>  'required|unique:users_table,user_name,'.$id

if your primary key is not named 'id' In my case my primary key is user_id and table name is users_table and I want to update user_name

so I do it this way

'user_name' => 'required|unique:users_table,user_name,'.$id.',user_id'

Solution 5:[5]

Try this

'email' => 'unique:table_name,column_name,'.$this->id.',id'

$this->id will be the value from your request

Solution 6:[6]

Include Rule by writing

use Illuminate\Validation\Rule;

and write your validation code as follows:

 'Email' => [required,
            Rule::unique('driver_details')->ignore($id),
            ]

Here $id is the id of the email that you want to ignore during validation which is obtained from the controller.

Solution 7:[7]

Check This,

'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],

Check here https://laravel.com/docs/7.x/validation#rule-unique.

Solution 8:[8]

This took me a while to figure out but when you are dealing with update/create requests you also have access to the request object. Here I am enforcing that client names are unique but allowing currently edited client.

class CreateUpdateClientRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => [
                'required',
                'string',
                'min:3',
                'max:50',
                Rule::unique('clients')->ignore($this->request->get('id'))
            ],
            'primary_contact_name' => 'required|string|min:3|max:50',
            'primary_contact_email' => 'required|string|email|min:5|max:50',
            'primary_contact_phone' => 'nullable|string|min:5|max:50',
            'secondary_contact_name' => 'nullable|string|min:3|max:50',
            'secondary_contact_email' => 'nullable|string|email|min:5|max:50',
            'secondary_contact_phone' => 'nullable|string|min:5|max:50',
            'notes' => 'nullable'
        ];
    }
}

Solution 9:[9]

In Laravel 6 app it helped me to exclude current user's email from validation:

use Illuminate\Validation\Rule;

public function update(Request $request, $id)
{
    $request->validate([
        'email' => [
            'email',
            'required',
             Rule::unique('claims')->ignore($id),
        ],
    ]);

    // ...
}

Solution 10:[10]

there is a shorter way, in my case I'm using route model binding, the URL format is

/something/{user}/something

return [
        'level' => 'required|max:5|unique:users,level,'. optional($this->user)->id,
    ];

Solution 11:[11]

Laravel 8:

    $request->validate([
        'email' => 'required|unique:users,email,'. $user->id,
    ]);

Solution 12:[12]

Been facing this issue for a while also. Try this:

$v = Validator::make($request->all(), [
    'email' => ['required',
    Rule::unique('<table_name>')->ignore(<your_table_id_to_ignore>),
    ]
]);

Works on Laravel 5.8. I don't know if it does work on lower versions of Laravel.

Solution 13:[13]

<?php

namespace App\Http\Requests\Admin\User;

use App\Model\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;


class UpdateRequest extends FormRequest
{
    protected $id;

    public function __construct(Request $request)
    {
        $this->id = (integer) $request->route()->user;
    }

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'first_name' => 'required|max:20',
            'last_name' => 'nullable|max:20',
            'mobile' => 'required|size:10|unique:users,mobile,'.$this->id,
           
        ];
    }
}

Solution 14:[14]

Try to use the Rule::unique('users')->ignore(Auth::id())

    //Validation
    $data = $request->validate([
        'username' => ['required', Rule::unique('users')->ignore(Auth::id()), 'min:4'],               //Verificar que este seleccionado sea único {Exceptuando mi mismo}
        'content' => 'required|min:6',
        'cover' => 'required|image'
    ]);

Solution 15:[15]

I use the same rule for create and update. But for update, I need it to ignore self.

This is what I use:

public function rules()
{
    return [
        'email' => [
            'required',
            'email',
            Rule::unique('users')->ignore($this->user->id ?? 0),
        ],
        // ...other fields
    ];
}

If update, then $this->user->id will be ignored. Otherwise if it's create, it will ignore id 0, which doesn't exist anyway.

Solution 16:[16]

It'll work...

$this->validate($request, 
    [
        'name' => 'required|unique:your_table_name,column_name,'.$request->auto_increment_id
    ],
    [
        'name.required' => 'Name should not be empty',
        'name.unique' => 'Name Already Exists'
    ]
);

Solution 17:[17]

you can try like this with check if deleted at column is null or not

for example:

$this->validate($request, [
  'email' => 'required|string|max:255|unique:table_name,email,'.$request->id.',id,deleted_at,NULL'
]);

Solution 18:[18]

This worked for me on Laravel 8.

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required|string',
            'email' => [
                'required',
                'email',
                Rule::unique('users', 'email')->ignore($this->user)
            ]
        ];
    }
}

Solution 19:[19]

This is other solution, pay attention over route parameter, is the "id" of user. Compare with solution mentioned by Arian Acosta.

Route:

Route::patch('users/{id}', [UserController::class, 'update']);

Controller:

public function update(UserRequest $request, $id) 
{
    // ...
}

Form Request:

class UserRequest extends FormRequest
{
    public function rules()`
    {
        return [
            'name' => 'required|string',
            'email' => 'required|email|unique:users,email,'.$this->id.',id',
        //...
        ];
    }
    //...
}

Solution 20:[20]

    'phone' => 'string|required|max:11|min:11|unique:users,phone,'.Auth::user()->phone.',phone'

Solution 21:[21]

i normaly make a rules array on controller construct, like this:

public function __construct()
{
    $this->rules = [
    'name' => 'required',
    'isCPNJ' => 'required',
    'CPF_CNPJ' => 'required',
    'password' => 'sometimes',
    'role_id' => 'sometimes',
    ];
 }

And then, when i need to validate somenthing specific, like the id and email on update, i create a specificRules variable and concatenate the id that i wish to ignore in the end of the rule,like this:

//Add the original rules to specificRules, just to make things more readable
$specificRules = $this->rules;
//Add the new rules
$specificRules['email'] = 'required|email|unique:users,email,' . $request['id'];
$specificRules['id'] = 'required|exists:users';
//Validate and save in $postData
$postData = $this->validate($request, $specificRules);

If someone has a more cleaner and simple way, please let me know :D

Solution 22:[22]

  $validator = validator()->make($request->all(), [
            'product_name'  => 'required|min:10|unique:products,name,'.$id,
            'product_slug'  => 'required|min:10|unique:products,slug,'.$id,
            'product_desc'  => 'required',
            'short_desc'    => 'required',
            'color'         => 'required',
            'product_sku'   => 'required|unique:products,sku,'.$id,
            'offer_price'   => 'required',
            'actual_price'  => 'required',
            'product_size*' => 'required',
            'product_image*'=> 'required|mimes:jpeg,png,jpg',
            'product_brand' => 'required',
            'product_meta'  => 'required',
        ]);

    if($validator->fails()) {
        $messages = $validator->messages();
        return redirect()->back()->withErrors($messages);
    }

this $id Forcing a unique rule to ignore a given id this is working for me