I wan't to be able to validate a user email address based on certain circumstances.
For example
If a user is being created, the email address must be unique
If a user is being updated but the email address hasn't changed, ignore the unique email rule
If a user is being updated and their email address has changed, it has to be unique
I've had a little look around and I know that I can specify different rules based on the method like so
public function rules()
{
$user = User::find($this->users);
switch($this->method())
{
case 'POST':
{
return [
'user.email' => 'required|email|unique:users,email',
];
}
case 'PUT':
case 'PATCH':
{
return [
'user.email' => 'required|email,
];
}
default:break;
}
}
Is there any way to make it so that in the put/patch case, the rule checks if the email address has been changed, and if it has then it has to be unique?
If not is there a cleaner way of achieving this goal? Maybe without the switch case? Perhaps more in depth validation rules I haven't stumbled across yet?
If i understand you correctly, you want to add unique
validation if email changed, if that is the case then you just need to add a condition in validation. If you check unique validation structure it look like this unique:table,column,except,idColumn
, check documentation
So the validation will be look like this, when you will create new record $userId
will be null but at time of patch it will have value. So this validation will work for both create and patch.
$userId = isset($user) ? $user->id : null;
$rules = [
'email' => 'required|email|unique:users,email,'. $userId.',id',
];
$this->validate($request, $rules);
I had a similar issue and found a tidy way of addressing it in the docs.
My issue was that if a user was already created, the email address claimed it wasn't unique, even if it was already registered to the user.
https://laravel.com/docs/8.x/validation#rule-unique
A few headings down is something like this:
use Illuminate\Validation\Rule;
$request->validate([
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);
This does the following:
Validate the email address, make it required and unique, unless the user ID of that row matches this user.
There is a built-in feature for this. You can add the actual user id to the unique constraint, if present. This will ensure that the unique constraint will still work, but it will not fail when the value did not change:
$exists = $user->exists;
$rules = return [
'user.email' => 'required|email|unique:users,email' . ($exists ? ','.$user->id : ''),
];
Internally, this will execute a query like:
SELECT count(id) FROM users WHERE email = '[email protected]' AND id != 42
The latter part AND id != 42
will only be part of the query when you add the third parameter to the unique validation rule.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With