Laravel request unknown number of validate parameters - laravel

I have 3 parameters that I send through request body.
At least one of them is necessary, others are optional, but it could be all 3 that would be send.
How should I validate this data? sometimes rule helps with optional parameters but how do I define that at least 1 is required?

You can use required_without as
$request->validate([
'first' => 'required_without:second,third',
'second' => 'required_without:first,third',
'third' => 'required_without:first,second',
]);
In this way you can validate at least one from three fields among (first,second and third)
Explanation of
'first' => 'required_without:second,third',
first must be present in absence or if empty of both second and third

Related

Laravel validate array values contained in list

I am passing an array in a request to my api. Each value within the array must be within a pre-defined list.
If my list is: name,description,title
name, title //valid
different, title //invalid
I tried array|in:name,description,title but I think for that I can only pass a string.
Can I do this without using a custom rule?
Validate each string in the array:
'values.*' => 'string|in:name,title,description'
Have a look at "Validating Nested Array Input"
If I understand you correctly your validation rules should be (untested)
[
'*.name' => 'required|string',
'*.description' => 'required|string',
]
Maybe you also want to exclude unvalidated Keys

Laravel validation gte rule

I am working on a web app and I needed to validate a form. The form has two numeric fields and I need to make sure one is greater than or equal to the other.
So I used these rules.
[
'adults' => ['required', 'numeric'],
'people' => ['required', 'numeric', 'gte:adults'],
]
Everything else is working except in one case. Say adults is missing or null but people is not. Then I would expect adults is required message. But instead I get
InvalidArgumentException: The values under comparison must be of the same type.
So it seems gte rules is comparing types of the two fields even when one is null with a required rule. How can I get around this?
I think it is a problem with the order the rules are evaluated.
If adults is evaluated first, It would fail with adults is required error. However, in case people is evaluated first, it tries to compare it to adults, throwing the error. You could solve this by conditionally adding the last rule:
[
'adults' => ['required', 'numeric'],
'people' => ['required', 'numeric', $request->has('adults') ? 'gte:adults' : ''],
]

Laravel: validate format when at least one of two input fields required

Suppose, in the feedback form we want to ask at least one of two contacts: email and/or telephone number. So, in the validation rules will be required_without for each other:
$this->validate($request, [
'email' => 'required_without:tel|email',
'tel' => 'required_without:email|regex:/(01)[0-9]{9}/'
], $messages);
We need to validate the contact data format only when it has been inputted, but in the code above the format of both fields will be checked. Because we need at least one contact, sometimes rule is no use.

Laravel 5.4 different value validation rule in array

I have an input with an array of entities with an ID which must be unique
I've tried this:
'authors.*.id' => 'different:authors.*.id'
But it says 'The authors.0.id and authors.0.id must be different'
So what is a right way to validate this?
You want to use distinct rule.
When working with arrays, the field under validation must not have any duplicate values.
'foo.*.id' => 'distinct'

First Or Create

I know using:
User::firstOrCreate(array('name' => $input['name'], 'email' => $input['email'], 'password' => $input['password']));
Checks whether the user exists first, if not it creates it, but how does it check? Does it check on all the params provided or is there a way to specifiy a specific param, e.g. can I just check that the email address exists, and not the name - as two users may have the same name but their email address needs to be unique.
firstOrCreate() checks for all the arguments to be present before it finds a match. If not all arguments match, then a new instance of the model will be created.
If you only want to check on a specific field, then use firstOrCreate(['field_name' => 'value']) with only one item in the array. This will return the first item that matches, or create a new one if not matches are found.
The difference between firstOrCreate() and firstOrNew():
firstOrCreate() will automatically create a new entry in the database if there is not match found. Otherwise it will give you the matched item.
firstOrNew() will give you a new model instance to work with if not match was found, but will only be saved to the database when you explicitly do so (calling save() on the model). Otherwise it will give you the matched item.
Choosing between one or the other depends on what you want to do. If you want to modify the model instance before it is saved for the first time (e.g. setting a name or some mandatory field), you should use firstOrNew(). If you can just use the arguments to immediately create a new model instance in the database without modifying it, you can use firstOrCreate().
As of Laravel 5.3 it's possible to do this in one step with firstOrCreate using a second optional values parameter used only if a new record is created, and not for the initial search. It's explained in the documentation as follows:
The firstOrCreate method will attempt to locate a database record using the given column / value pairs. If the model cannot be found in the database, a record will be inserted with the attributes resulting from merging the first array argument with the optional second array argument.
Example
$user = User::firstOrCreate([
'email' => 'dummy#domain.example'
], [
'firstName' => 'Taylor',
'lastName' => 'Otwell'
]);
This returns the User for the specified email if found, otherwise creates and returns a new user with the combined array of email, firstName, and lastName.
This technique requires Mass Assignment to be set up, either using the fillable or guarded properties to dictate which fields may be passed into the create call.
For this example the following would work (as a property of the User class):
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['email', 'firstName', 'lastName'];
firstOrCreate() checks for all the arguments to be present before it finds a match.
If you only want to check on a specific field, then use firstOrCreate(['field_name' => 'value']) like:
$user = User::firstOrCreate([
'email' => 'abcd#gmail.com'
], [
'firstName' => 'abcd',
'lastName' => 'efgh',
'veristyName'=>'xyz',
]);
Then it checks only the email.
An update:
As of Laravel 5.3 doing this in a single step is possible; the firstOrCreate method now accepts an optional second array as an argument.
The first array argument is the array on which the fields/values are matched, and the second array is the additional fields to use in the creation of the model if no match is found via matching the fields/values in the first array:
See the Laravel API documentation
You can always check if in current instance the record is created with the help of
$user->wasRecentlyCreated
So basically you can
if($user->wasRecentlyCreated){
// do what you need to do here
}

Resources