I'm currently working on an API for a car dealership, small school project.
In the CarController, I'm working on the POST request for adding a car and I'm having some problems with the validation of data.
This is a sample of the kind of data I'd be receiving:
{
"model": "Q5",
"brand": "Audi",
"year": 2008,
"price": 44000,
"color": "blue",
"traction": "4x4",
"motor": {
"type": "gasoline",
"hp": 256,
"turbo": false,
"cylinders": 4,
"motor_liters": 2.0
},
"user_id": 1
}
Considering the format, I wrote the validation like this:
$request->validate([
'model' => 'required|string',
'brand' => 'required|string',
'year' => 'required|integer',
'price' => 'required|numeric',
'color' => 'required|string',
'traction' => 'required|string',
'motor' => [
'type' => 'required|string',
'hp' => 'required|integer',
'turbo' => 'required|boolean',
'cylinders' => 'required|integer',
'motor_liters' => 'required|numeric'
],
'user_id' => 'required|integer'
]);
However, when making the request, it gives me the following error from the Validator:
BadMethodCallException: Method Illuminate\Validation\Validator::validateRequired|string does not exist.
At this point I don't know if it's a typo, bad formatting or I have to handle nested JSONs differently, considering I have a UserController with a POST request that looks like this:
$request->validate([
'username' => 'required|string|min:5',
'password' => 'required|string'
]);
And it works perfectly.
If you want to try the API yourselves here's the link to the repo.
to validate nested fields you have to use dot notation and not nest arrays:
$request->validate([
'model' => 'required|string',
'brand' => 'required|string',
'year' => 'required|integer',
'price' => 'required|numeric',
'color' => 'required|string',
'traction' => 'required|string',
'motor.type' => 'required|string',
'motor.hp' => 'required|integer',
'motor.turbo' => 'required|boolean',
'motor.cylinders' => 'required|integer',
'motor.motor_liters' => 'required|numeric',
'user_id' => 'required|integer'
]);
Related
How to validate a request like for this example i want to create a custom validation for qualities based on a group type. I know how to create a custom validation for laravel but for the example below i want to create a validation for quality type based on its group type.
The payload below it just for demonstration.
$payload = [
'groups' => [
[
'type' => 'human',
'qualities' => [
[
'type' => 'hair',
'value' => 'blue'
],
[
'type' => 'height',
'value' => '188cm'
],
]
],
[
'type' => 'cat',
'qualities' => [
[
'type' => 'hair',
'value' => 'yellow'
]
]
]
]
];
You can use the wildcard, for example:
$request->validate([
'payload.*' => 'required|array',
'payload.*.type' => 'required',
'payload.*.qualities' => 'required|array',
'payload.*.qualities.*' => 'required'
]);
How to validate a laravel request object, I have this conditions
request()->validate([
'avatar' => 'required|image',
'display_name' => 'required|min:3|max:100',
'role_id' => 'required|integer',
'username' => 'required|unique:users|min:4|max:15',
'email' => 'required|email|unique:users',
'phone_number' => 'required|min:3',
'password' => 'required|min:6',
'country_id' => 'required|integer'
]);
But in my request it was stored in an object form, what should I do to make the validations work ?
You validate it the same way you validate a multi-dimensional array:
request()->validate([
'form.avatar' => 'required|image',
'form.display_name' => 'required|min:3|max:100',
'form.role_id' => 'required|integer',
'form.username' => 'required|unique:users|min:4|max:15',
'form.email' => 'required|email|unique:users',
'form.phone_number' => 'required|min:3',
'form.password' => 'required|min:6',
'form.country_id' => 'required|integer'
]);
If your form is an array of object, you can use wildcard
request()->validate([
'form.*.avatar' => 'required|image',
'form.*.display_name' => 'required|min:3|max:100',
'form.*.role_id' => 'required|integer',
'form.*.username' => 'required|unique:users|min:4|max:15',
'form.*.email' => 'required|email|unique:users',
'form.*.phone_number' => 'required|min:3',
'form.*.password' => 'required|min:6',
'form.*.country_id' => 'required|integer'
]);
For unique validation you can pass the field name on which you need to apply validation, by default it takes the key name.
You can use this for unique validation on object data:-
'form.username' => 'required|unique:users,username|min:4|max:15'
My incoming JSON object:
{
"date": "2018-10-10",
"fiche": 1,
"fiche_type": 2,
"description": "test",
"project_code": "444",
"invoces":
[
{
"id": 1,
"description": "Ol",
"amount": 300,
"type": "debit"
},
{
"id": 2,
"type" :"credit",
"description": "Ol2",
"amount": 200
}
]
}
Validation rules are:
public function rules()
{
return [
'date' => 'required|date_format:Y-m-d',
'fiche' => 'required|integer',
'fiche_type' => 'required|integer',
'description' => 'string',
'project_code' => 'string',
'invoices' => 'required|array',
'invoices.id' => 'required|integer',
'invoices.description' => 'string',
'invoices.amount' => 'required|numeric',
'invoices.type' => 'required|string',
];
}
I always get a common error as: Wrong data validation
If you check closely to your validation rules, specifically:
return [
// ...
'invoices' => 'required|array',
'invoices.id' => 'required|integer', // <---
'invoices.description' => 'string', // <---
'invoices.amount' => 'required|numeric', // <---
'invoices.type' => 'required|string', // <---
];
With that setup, something like this should pass the validation (at least that part):
$invoices = [
'id' => 123,
'description' => 'a description',
'amount' => 123,
'type' => 'a type',
];
but that is not what you want.. you need to actually validate an array of items (array) with that structure:
$invoices = [
[
'id' => 123,
'description' => 'a description',
'amount' => 123,
'type' => 'a type',
],
[
'id' => 345,
'description' => 'another description',
'amount' => 156,
'type' => 'another type',
],
];
So.. what is the problem?
Well, before the item keys, you need to access the key of the item itself, but given that this rules will apply for every item in the array you need to make use of a wildcard. As the documentation says:
You may also validate each element of an array. For example, to
validate that each e-mail in a given array input field is unique, you
may do the following:
$validator = Validator::make($request->all(), [
'person.*.email' => 'email|unique:users',
'person.*.first_name' => 'required_with:person.*.last_name',
]);
Likewise, you may use the * character when specifying your validation
messages in your language files, making it a breeze to use a single
validation message for array based fields:
'custom' => [
'person.*.email' => [
'unique' => 'Each person must have a unique e-mail address',
] ],
So in your case:
return [
// ...
'invoices' => 'required|array',
'invoices.*.id' => 'required|integer', // <---
'invoices.*.description' => 'string', // <---
'invoices.*.amount' => 'required|numeric', // <---
'invoices.*.type' => 'required|string', // <---
];
Check the Validation Arrays section of the documentation.
in laravel 5.6 app I have table name as vehicles, then I need update some of table values in VehicleController update function with validation as this,
$this->validate($request, [
'provincename' => 'required|min:3',
'districtname' => 'required',
'townname' => 'required',
'brandname' => 'required',
'modelname' => 'required',
'year' => 'required',
'condition' => 'required',
'milage' => 'required',
'data' => 'required',
'price' => 'required',
'telephone' => 'required',
'categoryname' => 'required',
'tramsmission' => 'required',
'fueltype' => 'required',
'enginecapacity' => 'required'
]);
and my update controller is like this,
$vehicle = Vehicle::find($id);
$vehicle->provincename = $request->input('provincename');
$vehicle->districtname = $request->input('districtname');
$vehicle->townname = $request->input('townname');
$vehicle->brandname = $request->input('brandname');
$vehicle->modelname = $request->input('modelname');
$vehicle->modelyear = $request->input('year');
$vehicle->condition = $request->input('condition');
$vehicle->milage = $request->input('milage');
$vehicle->detail = $request->input('data');
$vehicle->price = $request->input('price');
$vehicle->telephone = $request->input('telephone');
$vehicle->categoryname = $request->input('categoryname');
$vehicle->transmission = $request->input('transmission');
$vehicle->fueltype = $request->input('fueltype');
$vehicle->enginecapacity = $request->input('enginecapacity');
$vehicle->user_id = Auth::user()->id;
$vehicle->save();
My update is ok. it is working. but with controller validation it is not updating. without validation it is working. how can fix this? what is the problem with this?
try this kind of validation format:
$validatedData = $request->validate([
'provincename' => 'required|min:3',
'districtname' => 'required',
'townname' => 'required',
'brandname' => 'required',
'modelname' => 'required',
'year' => 'required',
'condition' => 'required',
'milage' => 'required',
'data' => 'required',
'price' => 'required',
'telephone' => 'required',
'categoryname' => 'required',
'tramsmission' => 'required',
'fueltype' => 'required',
'enginecapacity' => 'required'
]);
EDIT
don't forget to use the validator. Add use Validator; after the namespace.
I am writing Validator in Laravel, and so I am getting json format request.
I have written validate logic for main json's fields such as id, name... Now I have items array of objects in json, and I need to validate each item from this array which is passed.
Here's example of json request: https://api.myjson.com/bins/ob3lh
And here's my validator so far:
private function update()
{
return [
'id' => 'required',
'place_id' => 'required',
'place_table_id' => 'required',
'user_id' => 'required',
'seen' => 'required',
'state' => 'required',
'number' => 'required',
'date' => 'required',
'price' => 'required',
'table_number' => 'required',
'note' => 'required',
];
}
How can I add simply for example nested validator which will validate each of items object?
You can define nested validation rules like this:
private function update()
{
return [
'id' => 'required',
'place_id' => 'required',
'place_table_id' => 'required',
'user_id' => 'required',
'seen' => 'required',
'state' => 'required',
'number' => 'required',
'date' => 'required',
'price' => 'required',
'table_number' => 'required',
'note' => 'required',
'items' => 'required|array|min:1',
'items.*.id' => 'required',
'items.*.name' => 'required',
'items.*.amount' => 'required',
'items.*.price' => 'required',
];
}
You can find more info on this in the docs: https://laravel.com/docs/5.5/validation#validating-arrays