34
votes

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 ?

17
@patricus: I got your question, but in your answer you didn't say about how to get the $id, it will be ok if they do validate for their own profile they can get their id by Auth::user()->id and in case of admin doing those part to others parts, should i set session and get inside model ,,, ???user3388086
How are you currently getting the id of the record you are trying to update?patricus
i am sending all the values to the model, $validation = Validator::make($DriverData, DriverModel::$updaterules);user3388086
I have posted a new question here, which would be clear, can you have a look at here ,, stackoverflow.com/questions/28205762/…user3388086

17 Answers

56
votes

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

24
votes

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.

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

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.

7
votes

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'
6
votes

Try this

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

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

5
votes

Check This,

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

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

4
votes

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'
        ];
    }
}
4
votes

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),
        ],
    ]);

    // ...
}
1
votes

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.

1
votes
<?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,
           
        ];
    }
}
1
votes

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'
    ]);
1
votes

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.

1
votes

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'
]);
0
votes

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

0
votes

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'
    ]
);
0
votes

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

/something/{user}/something

and the validation I've written in

namespace App\Http\Requests

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