Laravel validator, unique value when update info - php

So i have validator that checks if reg_number is unique. I use it for creating new entries (that part works). However, when i try to update an existing one using another form - i get error that reg_number already exists (logical). So my question is how to edit the rule that it would make an exception when i try to update (update other fields and keep reg_number the same) and not create a new one. Found something in other forums (added at the end of the rule) but its not working. Code below:
public function rules()
{
return [
'reg_number'=>'required|max:6|min:6|unique:cars'.$this->cars['reg_number'],
'brand'=>'required',
'model'=>'required'
];
}
Cheers!

There's an example as to how to do this in the Laravel docs.
Basically, you add the ID for the model instance you want to be excepted from this rule. E.g.:
public function rules()
{
return [
'reg_number' => ['required', 'max:6', 'min:6', 'unique:cars,reg_number,' . $this->id],
'brand' => ['required'],
'model' => ['required'],
];
}

Related

e-mail validation rule in Laravel

I am doing validation this way.
$rules = [
'email'=> 'required|regex:/^.+#.+$/i|unique:tab_example,email,'.$this>get('example_id').',example_id'
];
return $rules;
However, I am not getting success.
The error informs that
the email already exists
What I want is that if the email already exists and is from the same user does not need to inform that the email already exists.
I do not know what the problem is in my code.
You can use
'email' => "required|email|unique:users,email,{$id},id",
The id should be replaced with the primary key column name of the table you use for the unique check. The {$id} should be defined before $rules array like:
$id = $request->route('user')
Sometimes, you may wish to ignore a given ID during the unique check.
For example, consider an "update profile" screen that includes the user name, e-mail address, and location. Of course, you will want to verify that the e-mail address is unique.
However, if the user only changes the name field and not the e-mail field, you do not want a validation error to be thrown because the user is already the owner of the e-mail address.
you can use like:
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
Try this
'email' => Rule::unique('users')->ignore($user->id, 'user_id');
Read Under the Section Forcing A Unique Rule To ignore A given Field
Try This way
$rules = [
'email'=> ['required', 'email', \Illuminate\Validation\Rule::unique('tab_example', 'email')->whereNot('example_id',$this->get('example_id'))]
];
Just use
$this->route('example_id')
instead of
$this>get('example_id')
And if you use resource route then use $this->route('user').
$rules = [
'email'=> 'required|regex:/^.+#.+$/i|unique:tab_example,email,'.$this->route('example_id').',example_id'
];
return $rules;

Laravel unique validation fails on update

I am using laravel 5.7 and using form request but i have a unique branch_name in my database as well as unique slug but every time on update valdiation erorr .branch name already exist
public function rules()
{
switch($this->method()) {
case 'DELETE':
return [
'slug'=>'required',
];
case 'POST':
case 'PUT':
case 'PATCH':
return [
'branch_name'=>'required|max:255|unique:branches,branch_name,id'.$this->id,
'branch_address'=>'required',
];
default:
break;
}
}
and also i tried the following but no use
'branch_name'=>'required|max:255|unique:branches,branch_name,'.$this->id,
and
'branch_name'=>'required|max:255|unique:branches,branch_name,slug'.$this->slug,
also i have a hidden value for both id as well as for slug even i printed in on rule method i can see id and slug
This will do:
use Illuminate\Validation\Rule;
'branch_name' => [
'required|max:255',
Rule::unique('branches')->ignore($this->route('branch')),
]
Replace "branch" with route parameter name from your edit route of web.php.
You can use this validation in add and edit both.
if your database field name is different then send the name as the second parameter in ignore function. Like
Rule::unique('branches')->ignore($this->route('branch'), 'branchName'),
Details: Laraval Validation unique
Hope this helps.
Try this one
use Illuminate\Validation\Rule;
'branch_name' => [
'required|max:255',
Rule::unique('branches')->ignore($branches->id),
],
unique:table,column,except,idColumn
The field under validation must be unique in a given database table. If the column option is not specified, the field name will be used.
validation
'branch_name' => 'required|max:255|unique:branches,branch_name,' . $this->id . ',id',
OR
'branch_name'=>'required|max:255|unique:branches,branch_name,' . $this->slug . ',slug',

Laravel Validation Rules If Value Exists in Another Field Array

I am working in Laravel 5.4 and I have a slightly specific validation rules need but I think this should be easily doable without having to extend the class. Just not sure how to make this work..
What I would like to do is to make the 'music_instrument' form field mandatory if program array contains 'Music'.
I found this thread How to set require if value is chosen in another multiple choice field in validation of laravel? but it is not a solution (because it never got resolved in the first place) and the reason it doesn't work is because the submitted array indexes aren't constant (not selected check boxes aren't considered in indexing the submission result...)
My case looks like this:
<form action="" method="post">
<fieldset>
<input name="program[]" value="Anthropology" type="checkbox">Anthropology
<input name="program[]" value="Biology" type="checkbox">Biology
<input name="program[]" value="Chemistry" type="checkbox">Chemistry
<input name="program[]" value="Music" type="checkbox">Music
<input name="program[]" value="Philosophy" type="checkbox">Philosophy
<input name="program[]" value="Zombies" type="checkbox">Zombies
<input name="music_instrument" type="text" value"">
<button type="submit">Submit</button>
</fieldset>
</form>
If I select some of the options from the list of check boxes I can potentially have this result in my $request values
[program] => Array
(
[0] => Anthropology
[1] => Biology
[2] => Music
[3] => Philosophy
)
[music_instrument] => 'Guitar'
Looking at validation rules here: https://laravel.com/docs/5.4/validation#available-validation-rules I think something like his should work but i am literally getting nothing:
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program,in:Music'
]);
I was hoping this would work too but no luck:
'music_instrument' => 'required_if:program,in_array:Music',
Thoughts? Suggestions?
Thank you!
Haven't tried that, but in general array fields you usually write like this: program.*, so maybe something like this will work:
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program.*,in:Music'
]);
If it won't work, obviously you can do it also in the other way for example like this:
$rules = ['program' => 'required'];
if (in_array('Music', $request->input('program', []))) {
$rules['music_instrument'] = 'required';
}
$validator = Validator::make($request->all(), $rules);
I know this post is older but if someone came across this issue again.
$validator = Validator::make($request->all(),[
'program' => 'required',
'music_instrument' => 'required_if:program,Music,other values'
]);
You could create a new custom rule called required_if_array_contains like this...
In app/Providers/CustomValidatorProvider.php add a new private function:
/**
* A version of required_if that works for groups of checkboxes and multi-selects
*/
private function required_if_array_contains(): void
{
$this->app['validator']->extend('required_if_array_contains',
function ($attribute, $value, $parameters, Validator $validator){
// The first item in the array of parameters is the field that we take the value from
$valueField = array_shift($parameters);
$valueFieldValues = Input::get($valueField);
if (is_null($valueFieldValues)) {
return true;
}
foreach ($parameters as $parameter) {
if (in_array($parameter, $valueFieldValues) && strlen(trim($value)) == 0) {
// As soon as we find one of the parameters has been selected, we reject if field is empty
$validator->addReplacer('required_if_array_contains', function($message) use ($parameter) {
return str_replace(':value', $parameter, $message);
});
return false;
}
}
// If we've managed to get this far, none of the parameters were selected so it must be valid
return true;
});
}
And don't forget to check there is a use statement at the top of CustomValidatorProvider.php for our use of Validator as an argument in our new method:
...
use Illuminate\Validation\Validator;
Then in the boot() method of CustomValidatorProvider.php call your new private method:
public function boot()
{
...
$this->required_if_array_contains();
}
Then teach Laravel to write the validation message in a human-friendly way by adding a new item to the array in resources/lang/en/validation.php:
return [
...
'required_if_array_contains' => ':attribute must be provided when ":value" is selected.',
]
Now you can write validation rules like this:
public function rules()
{
return [
"animals": "required",
"animals-other": "required_if_array_contains:animals,other-mamal,other-reptile",
];
}
In the above example, animals is a group of checkboxes and animals-other is a text input that is only required if the other-mamal or other-reptile value has been checked.
This would also work for a select input with multiple selection enabled or any input that results in an array of values in one of the inputs in the request.
The approach I took for a similar problem was to make a private function inside my Controller class and use a ternary expression to add the required field if it came back true.
I have roughly 20 fields that have a checkbox to enable the input fields in this case, so it may be overkill in comparison, but as your needs grow, it could prove helpful.
/**
* Check if the parameterized value is in the submitted list of programs
*
* #param Request $request
* #param string $value
*/
private function _checkProgram(Request $request, string $value)
{
if ($request->has('program')) {
return in_array($value, $request->input('program'));
}
return false;
}
Using this function, you can apply the same logic if you have other fields for your other programs as well.
Then in the store function:
public function store(Request $request)
{
$this->validate(request(), [
// ... your other validation here
'music_instrument' => ''.($this->_checkProgram($request, 'music') ? 'required' : '').'',
// or if you have some other validation like max value, just remember to add the |-delimiter:
'music_instrument' => 'max:64'.($this->_checkProgram($request, 'music') ? '|required' : '').'',
]);
// rest of your store function
}
Here my piece of code to solve that kind of trouble usind Laravel 6 Validation Rules
I tried to use the code above
public function rules()
{
return [
"some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
"another_field" => ["nullable", "required_if:operacao.*,in:1"],
];
}
I need that when some_array_field has 1 in your value, another_field must be validated, otherwhise, can be null.
With the code above, doesn't work, even with required_if:operacao.*,1
If I change the rule for another_field to required_if:operacao.0,1 WORKS but only if the value to find is in index 0, when the order changes, validation fails.
So, I decided to use a custom closure function
Here's the final code for the example that works fine form me.
public function rules()
{
return [
"some_array_field.*" => ["required", "integer", "in:1,2,4,5"],
"another_field" => [
"nullable",
Rule::requiredIf (
function () {
return in_array(1, (array)$this->request->get("some_array_field"));
}
),
]
];
}
I hope that solve your trouble too!

Laravel 5.2 - validation - One of the fields is required

Take a scenario,
There are 2 fields available in the form.
1) input type file for manual upload.
2) input type = text to enter youtube video url.
is it possible using laravel built-in validations so that validation will be fired if user has left both fields empty!
I have gone through https://laravel.com/docs/5.3/validation but could not find what I wanted.
In your controller, you could do something like this:
$validator = Validator::make($request->all(), [
'link_upload' => 'required|etc|...',
]);
$validator2 = Validator::make($request->all(), [
'file_upload' => 'required|etc|...',
]);
if ($validator->fails() && $validator2->fails()) {
// return with errors
}
Try required-without-all validation rule. As given in documentation:
The field under validation must be present only when the all of the other specified fields are not present.
Assuming your fields name are url and file, your rule would be like below:
$rules = [
'url' => 'required_without_all:file',
'file' => 'required_without_all:url'
];
required_without:foo,bar,...
The field under validation must be present and not empty only when any of the other specified fields are not present.
Try this,
In youre update method add this
$this->validate($request, [
'fileName'=>'required',
'urlName'=>'required'
]);
dont forget to set the fillable in your model
protected $fillable = ['fileName','urlName'];
Hope this helps

Laravel rule for unique excluding blank or null

I have a user model that needs to have unique email addresses but I also want to allow them to be left blank in case the user has no email...I see in docs there is a way to make a rule for unique and an exception for an id...but I'm not sure how to make this allow null or blank but unique if it is not. Sorry seems like this is simple but I can't think of the answer.
public static $adminrules =
'email' => 'email|unique:users,email,null,id,email,NOT_EMPTY'
);
Edit It may be that using the rule without required is enough since a blank or null would pass validation in those cases. I might have a related bug that making it so I can't add more than 1 blank email, so I can't verify this.
public static $adminrules =
'email' => 'email|unique:users'
);
I tried this. Adding 'nullable' before 'sometimes'.
$validator = Validator::make($request->all(), [
'email' => 'nullable|sometimes|unique:users',
]);
You should try this:
$v->sometimes('email', 'email|unique:users,email', function($input)
{
return !empty($input->email);
});
$v is your validator object and you basically say that in case the email field is not empty it should also be unique (there shouldn't be a users table record with this value in email column).
In your Requests/UserRequest you'd have something like
public function rules()
{
return [
'email' => [
'nullable',Rule::unique((new User)->getTable())->ignore($this->route()->user->id ?? null)
]
];
}
The usage of nullable is what allows the field to be nullable. The other part is to check if the email is unique in the User model table.
If you wish to validate if the field is unique
between two fields please refer to this answer.
in another table, then add the following to your rules
'exists:'.(new ModelName)->getTable().',id'
You should try to change your structure of database to make the field email is nullable. And in the rules try this :
$this->validate($request,
[
'email' => 'email',
]
);
if(isset($request->address))
{
$this->validate($request,
[
'email' => 'email|unique:users'
]
);
}

Categories