Using Laravel 5.4, my users have an auto-complete helper to put values into an input. I want to validate that each of the values exists in the database when inserting.
Inputted value for "unit" : "12,13,14"
How do I check that, unit "12" and unit "13" and unit "14" exist in the database before doing the insert?
$units = array_filter(array_unique(explode(",", $request->unit)));
// input "12,13,14" becomes [12,13,14]
$this->validate($request,[
'unit' => 'required|exists:units.id,'.$units,
]);
Do I have to use a custom validation rule, or does laravel have something handy like 'required|existsAllValuesInThisArray' sorta thing? Haven't found anything in documentation about it.
I also found this, but it's for like multiple select fields or checkboxes sorta thing from the looks of it.
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Update : I ended up using javascript to split the input into an array before sending it off for processing. So my input name became "units[]" instead of "units"
Try the following:
$this->validate($request,[ 'unit.*' => 'required|exists:units.id,'.$units, ]);
Since $units is an array, the rule unit.* should check for each element of the array.
Related
I have two datepicker input fields: from and to. To ensure that field value to is greater than field value from, I use the after validation rule. Everything is fine up until I leave the from input value null. Because I am applying the validation rule using the input value from.
How can I combine the required and after validation rules without running into this problem?
$from = $request->input('from');
$from = Carbon::createFromFormat('Y-m-d\TH:i', $from)->format('Y-m-d H:i A');
$attributes= request()->validate([
'from' => 'required|date',
'to'=> 'nullable|date|after:'.$from,
]);
Data missing error while from input value is empty.
The laravel validation rule allows you to compare a field against another field. So you can simply add: after:from
See the documentation here.
$attributes = request()->validate([
'from' => 'required|date',
'to'=> 'nullable|date|after:from',
]);
In Laravel 9 with PHP 8.1, I can not compare backed enum in laravel validation rules where you can use ->where clause. It needs a scalar value to compare. Are there any other ways to compare with an enum object rather than scalar value?
validator($attributes, [
'manager_id' =>
[
'required',
'integer',
Rule::exists(User::getTableName(), 'id'),
Rule::unique(JProject::getTableName(), 'manager_id')
->where('status', JProjectStatus::Active)
]
])->validate();
JProjectStatus is a backed enum
enum JProjectStatus: string
{
case Active = 'active';
case Inactive = 'inactive';
case Blocked = 'blocked';
}
When I'm trying to check the manager is unique where the project is active or not, I encountered a type error and I totally understand that it is comparing string with enum object.
message "str_replace(): Argument #3 ($subject) must be of type
array|string, App\Enums\JProjectStatus given" exception "TypeError"
But if I write like below which is a scaler value that's totally fine with str_replate().
validator($attributes, [
'manager_id' =>
[
'required',
'integer',
Rule::exists(User::getTableName(), 'id'),
Rule::unique(JProject::getTableName(), 'manager_id')->where('status', JProjectStatus::Active->value)
]
])->validate();
Because now 'JProjectStatus::Active->value' is a scalar value of 'active'
Sure, I can pass a closure in where condition but want to know the best practice. My question is, Is it okay to write like this, or is there any other way to write best practice with enum object.
Yes, it is possible, i'm using my backed enum in this way
$request->validate([
'state' => ['required', new Enum(ActiveStatus::class)],
]);
and import this file in controller
use Illuminate\Validation\Rules\Enum;
Laravel Enums only works with Laravel 9 with PHP-8.1
I have three nullable fields ( Coupon, Membership, Offer) which are to be filled from requests. I want to validate/restrict users so that they can only fill one of these fields.
As the fields are not required, I cannot use the required:* validators to handle this.
I know this can be handled in the front-end, but I want to do it in the backend as well.
Appreciate any help/insight on this.
You can use required_without_all function from laravel validations.
$request->validate([
'coupon' => ['nullable', 'required_without_all:membership,offer'],
'membership' => ['nullable', 'required_without_all:coupon,offer'],
'offer' => ['nullable', 'required_without_all:membership,coupon'],
]);
I would take the approach of having the options as three possible values for the same field. You could use a select or radio button group on your form to fill in a single field. This way the user can only enter one of the three possible values.
If we call the field type for example, your validation would check that the value given for type is one of the three options.
$request->validate([
'type' => [
'nullable',
Rule::in(['coupon', 'membership', 'offer']),
],
]);
EDIT:
Add the nullable validation to allow the field to have no value at all
I have a dynamic phone number validation rule, and I need 2 values for it: number and country.
The library I'm using to validate the phone number is brick/phonenumber which can include the country code to parse it accurately.
So, my current working approach looks like this:
$request->validate([
'country' => ['required', 'max:2'],
]);
$request->validate([
'number' => ['required', new PhoneNumberValidator($request->input('country')],
]);
Because when I put it like this:
$request->validate([
'country' => ['required', 'max:2'],
'number' => ['required', new PhoneNumberValidator($request->input('country'))],
]);
The number validation runs even if the country is not valid. So I'd like to know if there's a way to have all the validations in one validate() call, so, having the country value validated before calling the number rule (I tried with bail but that stops the validations for 1 attribute, not the rest of attributes in the queue).
You can create a custom rule and validate both inputs at the same time.
You may also want to look at the various validation rules. You might find something helpful.
Since upgrading laravel from 5.1 to 5.3, I've got couple of odd issues with Validation.
When I post a data like this:
firstName null
And the validation rules are like this:
$validator = Validator::make($postData, [
'firstName' => 'string|max:255',
'lastName' => 'string|max:255'
]);
The above fails with the messages something like "The XYZ must be a string.". What I don't understand is:
Why is the validation failing when it is not set as required?
Meaning, it should ignore it and not throw an error if the value is
empty, right?
Why does the validation fail if the value is set as null?
Why does the validation fail when the parameter is not sent at all?
(like the lastName which is not posted at all)
Has something changed in Laravel 5.3 validations?
Add nullable rule:
'firstName' => 'string|max:255|nullable',
'lastName' => 'string|max:255|nullable'
The field under validation may be null. This is particularly useful when validating primitive such as strings and integers that can contain null values.
When you want something to be required but the value itself can be empty, like an empty string.
Validator::make($postData, [
'firstName' => 'present|string|max:255|nullable',
'lastName' => 'present|string|max:255|nullable'
]);
Useful in scenarios like "notes", which can be emptied by removing the input field from all its text and hit save.