Laravel - exclude current email from unique validation - laravel

I am trying to use unique on an email address in Laravel 5.5 validation like this..
$rules = [
'email' => 'email|unique:users,email,
];
This is working and is checking the 'users' table in the 'email' column
But if the email address is the same as the currently saved one then this also fails validation.
Is there a way I can add an exception rule to the validation to ignore $user-email?

The unique rule takes a third parameter: a record to ignore, see "Forcing A Unique Rule To Ignore A Given ID".
Pass in the ID of the record you do not wish to be included in the unique test, e.g:
$rules = [
'email' => 'email|unique:users,email,' . $user->id
];

THIS IS AN EASY SOLUTION
Just add $this->route('id') as the third parameter
if your route was defined like this:
Route::put('{company}', 'CompanyController#update')
->name('update');
then your parameter name is "company"
So in your FormRequest:
public function rules()
{
$rules = [
'url' => [
'required',
'url',
'unique:companies,url,'.$this->route('company') ?? 0
],
];
// dd($rules); << check yourself
return $rules;
}
This FormRequest works the same for insert or update.
this line will instruct to ignore "0" in case of insert
$this->route('company') ?? 0

Related

The unique Rule validation is not applied

I am using laravel 9.
And I have this very simple validation rule (form request validation):
public function rules()
{
return [
'first_name' => 'required|max:50',
'last_name' => 'required|max:50',
'email' => [
'email',
Rule::unique('unknown_table')->where(function ($query) {
return $query->where('library_id', $this->library->id);
})
],
.......
What I do not understand is why my post is working with this table name "unknown_table", because this table really does not exist. I expected an exception but nothing happens !
Is this rule correctly written ?
I have understood my error. The "email" validation was twice in the rule array ! And it was the last one which was used of course.

Laravel validation exists in this table OR that table

I need to validate the existence of an API request parameter
but check it in one of two tables, users and teachers
something like this
$rules = ['apiToken' => 'required|string|min:70|exists:users,api_token ((OR)) exists:teachers,api_token']
is there a way to achieve this using Laravel validator?
For something like this you will probably need to use custom validation:
$rules = [
'apiToken' => [
'required', 'string', 'min:70', function ($attribute, $value, $fail) {
if (!DB::table('users')->where('api_token', $value)->exists() || !DB::table('teachers')->where('api_token', $value)->exists()) {
return $fail("The provided $attribute is not valid.");
}
}
]
];
You can change the returned error message by editing the text passed to the $fail function.

I need to apply validation on the combination of columns in laravel model rule

public static $rules = [
'name' => 'min:3|unique:enterprise,name|required',
'lang_id'=> 'min:1|unique:lang_id',
];
This is rule for separate column validation but I need if either column name or lang_id is different then value should be updated
Use the different validation:
The field under validation must have a different value than field.
public static $rules = [
'name' => 'min:3|unique:enterprise,name|required|different:lang_id',
'lang_id'=> 'min:1|unique:lang_id|different:name',
];
As found in the documentation at https://laravel.com/docs/5.5/validation#rule-different

Email validation rule in Laravel?

I do email validation using the simple rule:
'email' => 'required|email|unique:users,email',
How do I modify the option unique so that it will work only if the entered email is different from the primordial?
A sample:
The field email contains the default value from table users: example#gmail.com
Then I push the button without making any changes in the form I should not check unique:users.
Otherwise, if I even changed one symbol in example#gmail.com1 I must validate the incoming value using: unique:users.
You can find an example here https://laracasts.com/discuss/channels/requests/laravel-5-validation-request-how-to-handle-validation-on-update
You will need to have multiple rules depending on the request method (update or create) and you can pass a third parameter to unique to ensure no fail if you know the user / email
'user.email' => 'required|email|unique:users,email,'.$user->id,
Switch for method
switch($this->method())
{
...
}
I did this using the conditional checks:
$validator = Validator::make($request->all(), []);
$validator->sometimes('email', 'unique:users,email', function ($input) {
return $input->email !== Auth::user()->email;
});
I think it is as loophole in laravel validation.
I update the code for email validation. This is working fine for me.
'email' => [
'required', 'email:rfc',
function($attribute, $value, $fail) {
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$fail($attribute . ' is invalid.');
}
}],

CakePHP Validate a specific rule only when a couple required fields aren't empty

I wrote a custom rule method for validating whether a record exists in the DB before adding a new record. I put the method in a behavior so I could share it with other models, but I've run into a chicken and egg situation.
In order to know whether a category has a specific group name already I need to have the category id, and the group name. So I pass those keys through using my custom rule (category_id and name). But, this won't work since if I don't choose a category_id by mistake then the query will occur on just the name, so I patched this with a couple lines, but need to return true if this is the case and bank on the category_id validation being invalid.
Is there a better way to implement this kind of validation? Is this not as bad as I think? Or just don't bother and in my controller drop hasAny() under my call to validates() if it passes.
MODEL:
public $validate = [
'category_id' => [
'rule' => 'notEmpty',
'message' => 'Category is required.'
],
'name' => [
'notEmpty' => [
'rule' => 'notEmpty',
'message' => 'Team is required.'
],
'recordExists' => [
'rule' => [ 'recordExists', [ 'category_id', 'name' ] ],
'message' => 'Group already exists.'
]
]
];
// BEHAVIOR:
public function recordExists( Model $Model, $conditions, $requireKeys )
{
// Overrite conditions to
$conditions = $Model->data[ $Model->name ];
// Trim all array elements and filter out any empty indexes
$conditions = array_map( 'trim', $conditions );
$conditions = array_filter( $conditions );
// Get the remaining non-empty keys
$conditionKeys = array_keys( $conditions );
// Only query for record if all required keys are in conditions
if (empty( array_diff( $requireKeys, $conditionKeys ) )) {
return !$Model->hasAny( $conditions );
}
// NOTE: seems wrong to return true based on the assumption the category_id validation has probably failed
return true;
}
Use the beforeValidate() callback of the model to check if the fields are present and if they're empty. If they're empty just unset() the recordExists validation rule in your models validation property. Copy them to a temporary variable or property in the case you want to set them back after your current operation.
And use $Model->alias, name will break if the model is used through an association that has a different name.
$conditions = $Model->data[ $Model->name ];

Resources