Luiz
Luiz

Reputation: 2539

How validate unique email out of the user that is updating it in Laravel?

I am using Laravel 5.2 and want to update user's account using validator.

I want to keep email field unique, but, if the user type his current email it will break. How can I update if the email is unique, except the user's own current email?

Upvotes: 57

Views: 177278

Answers (12)

Pouyans
Pouyans

Reputation: 41

In laravel 9, you can do something like this In your Request file:

 public function rules()
    {
        return [
            Rule::unique('users')->ignore($this->id)
        ];
    }

Check Laravel documentation for unique validation: https://laravel.com/docs/9.x/validation#rule-unique

Upvotes: 4

Aamir Anwar
Aamir Anwar

Reputation: 175

$current_user  = Users::where('access_token', $request->access_token)->first();

$validator = Validator::make($request->all(), [ 
    'name'            => 'required|max:255',
    "email"           => "required|email|max:100|unique:users,email,".$current_user->id.",id",  
]);

Upvotes: 1

Neamul Mowla
Neamul Mowla

Reputation: 81

'email' => "required|email|unique:users,email,$id",

In a laravel 8. I also search for long time. this will work

Upvotes: 8

Mouhssine Soumairi
Mouhssine Soumairi

Reputation: 93

there's many methods :

1- In controller

public function update(Request $request, User $user)
{
  $request->validate([
      'email' => 'required|email|unique:users,email,'.$user->id,
  ]);
}

2-Form requests

Form requests are custom request classes that contain validation logic. Read more here.

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

Upvotes: 8

pankaj kumar
pankaj kumar

Reputation: 1

if($request->ID){
            $this->validate($request, [
                'name'      => 'required',
                'mobile'    => 'required|unique:schools,mobile,'.$request->ID,
                'email'     => 'required|unique:schools,email,'.$request->ID,
                'address'   => 'required',
            ]);
        }
        else{
            $this->validate($request, [
                'name'      => 'required',
                'mobile'    => 'required|unique:schools',
                'email'     => 'required|unique:schools',
                'address'   => 'required',
            ]);
        }

Upvotes: -1

Tiago Peres
Tiago Peres

Reputation: 15451

In order to update user's account you can create a class AccountRequest that extends FormRequest

<?php

namespace App\Http\Requests;

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

class AccountRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return auth()->check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => ['required', 'min:3'],
            'email' => [auth()->id() == 1 ? 'sometimes' : 'required', 'email', Rule::unique((new User)->getTable())->ignore(auth()->id())]
        ];
    }
}

Then, in your AccountController

namespace App\Http\Controllers;

use Gate;
use App\User;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\AccountRequest;

class AccountControllerextends Controller
{
    /**
     * Show the form for editing the account.
     *
     * @return \Illuminate\View\View
     */
    public function edit()
    {
        return view('account.edit');
    }

    /**
     * Update the account
     *
     * @param  \App\Http\Requests\AccountRequest  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(AccountRequest  $request)
    {

        auth()->user()->update(['name' => $request->get('name'),
                                'email' => $request->get('email')]);

        return back()->withStatus(__('Account successfully updated.'));
    }
}

and your routes would look like this

Route::get('account', ['as' => 'account.edit', 'uses' => 'AccountController@edit']);
Route::put('account', ['as' => 'account.update', 'uses' => 'AccountController@update']);

Upvotes: 0

Juan Carlos Ibarra
Juan Carlos Ibarra

Reputation: 1399

On Laravel 5.7+ to instruct the validator to ignore the user's ID, we'll use the Rule class to fluently define the rule. In this example, we'll also specify the validation rules as an array instead of using the | character to delimit the rules:

use Illuminate\Validation\Rule;

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

Upvotes: 9

Vincent Decaux
Vincent Decaux

Reputation: 10714

On Laravel 7 to build an API, if you want something clean, you can simply use :

public function rules()
{
    $emailRule = Rule::unique((new User)->getTable());

    if (request()->isMethod('put')) {
        // we update user, let's ignore its own email
        // consider your route like : PUT /users/{user}
        $emailRule->ignore($this->route('user'));
    }

    return [
        'name' => 'required',
        'email' => [
            'required',
            'email',
            $emailRule
        ],
    ];
}

You can get the user you want to update (using PUT method here) and ignore him.

Upvotes: 0

silvia zulinka
silvia zulinka

Reputation: 731

Creat form request and add this code on App/Http/Request/YourFormRequest class

public function rules()
{  // get user by uri segment
   $user = User::find((int) request()->segment(2)); 
   return [ 
        'name' => 'required|string|max:100', 
        'email' => 'required|email|unique:users,email,'.$user->id.',id' 
    ];
}

check the doc here

Upvotes: 2

Salam
Salam

Reputation: 1168

For coders using FormRequest & Laravel 5.7 and facing this problem, you can do something like this

public function rules() {

    return [
        'email' => ['required', 'string', 'email', 'max:255',
            Rule::unique('users')->ignore($this->user),
        ],
    ];

}

The $this->user will return the user ID coming from the request.

Upvotes: 9

Afraz Ahmad
Afraz Ahmad

Reputation: 5386

In Request Class you will probably need this validation in PUT or PATCH method where you don't have user then you can simply use this rule

 You have 2 options to do this

1:

 'email' => "unique:users,email,$this->id,id"

OR

2:

 use Illuminate\Validation\Rule; //import Rule class 
'email' => Rule::unique('users')->ignore($this->id); //use it in PUT or PATCH method

$this->id is providing id of the user because $this is object of Request Class and Request also contains user object.

public function rules()
{
    switch ($this->method()) {
        case 'POST':
        {
            return [
                'name' => 'required',
                'email' => 'required|email|unique:users',
                'password' => 'required'
            ];
        }
        case 'PUT':
        case 'PATCH':
        {
            return [
                'name' => 'required',
                'email' => "unique:users,email,$this->id,id",
                                   OR
                //below way will only work in Laravel ^5.5 
                'email' => Rule::unique('users')->ignore($this->id),

               //Sometimes you dont have id in $this object
               //then you can use route method to get object of model 
               //and then get the id or slug whatever you want like below:

              'email' => Rule::unique('users')->ignore($this->route()->user->id),
            ];
        }
        default: break;
    }
}

Hope it will solve the problem while using request class.

Upvotes: 45

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87719

You can tell that to validators:

'email' => 'unique:users,email_address,'.$user->id

Check the docs, in section 'Forcing A Unique Rule To Ignore A Given ID'.

Upvotes: 124

Related Questions