I'm trying to validate an array inside a custom Request. The rule evaluates to required if two conditions are met:
attribute3 is true
another column from the same array is true
Here's what I'm doing:
public function rules()
{
return [
'attribute1' => 'required',
'attribute2' => 'required',
'attribute3' => 'required',
...
'attribute10.*.column3' => Rule::requiredIf(fn() => $this->attribute3), // <- array
'attribute10.*.column4' => Rule::requiredIf(fn() => $this->attribute3), // <- array
'attribute10.*.column5' => Rule::requiredIf(fn() => $this->attribute3), // <- array
];
}
What I really need is this:
'attribute10.*.column4' => Rule::requiredIf(fn($item <- magically hint this currently looped item) => $this->attribute3 && $item->column2 <- so I can use it like this), // <- array
Assuming the incoming request has a structure like the following:
[
'attribute1' => 1,
'attribute2' => 0,
'attribute3' => 1,
'attribute10' => [
[
'column1' => 1,
'column2' => 1,
'column3' => 0,
],
[
'column1' => 0,
'column2' => 1,
'column3' => 0,
],
],
]
You can set the rules array to a variable, and then loop over the attribute10 field array elements and merge each rule on the rules variable. Then you'll have access to the other elements on the nested array.
Ie:
public function rules()
{
$rules = [
'attribute1' => 'required',
'attribute2' => 'required',
'attribute3' => 'required',
];
foreach($this->attribute10 as $key => $item) {
array_merge($rules, [
'attribute10.'.$key.'.column2' => Rule::requiredIf($this->attribute3 && $item['column1']),
'attribute10.'.$key.'.column3' => Rule::requiredIf($this->attribute3 && $item['column2']),
//...
]);
}
return $rules;
}
Related
How can I get data from another table?
// ServiceComplexController
public function index(Store $store): JsonResponse
{
/* #var User $user */
$user = auth()->user();
$this->listQuery = $user->store->serviceComplexes()->getQuery();
return response()->json([
'data' => StoreServiceComplexResource::collection($this->listQuery->get()),
]);
}
// StoreServiceComplexResource
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'base_service_ids' => $this->base_service_ids,
'more_service_ids' => $this->more_service_ids,
];
}
// Dump $this->listQuery->get()
array (
0 =>
array (
'id' => 3,
'name' => 'Complex 1',
'description' => 'Desc complex 1',
'base_service_ids' =>
array (
0 => 1,
1 => 2,
),
'more_service_ids' =>
array (
0 => 10,
),
),
)
How to get base services from another table(services) based on field "base_service_ids" and "more_service_ids" and add them to response ?
Is it possible to give this data also through Collection Resource ? For example
// StoreServiceComplexResource
public function toArray($request): array
{
return [
...
'service' => [] //StoreServiceResource::collection() ....
...
];
}
In image you can see name and I want to store on base of name
Array index 0 & 2 have the same name. And I want to store same name in one array
Like This:
Josue Koepp DDS => {
id=>2,
item_name=>"Domenic Labadie"
},
{
id=>0,
item_name=>"Prof. Jakayla Willms"
}
}
You can use groupBy()
$collection = collect([
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
['account_id' => 'account-x11', 'product' => 'Desk'],
]);
$grouped = $collection->groupBy('account_id');
$grouped->toArray();
/*
[
'account-x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'account-x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
In your case:
$lists = $lists->groupBy('name')->toArray();
I am trying to validate a multi dimensional array in Laravel. This whole input itself is not required, however, if it is present, all of its keys should have some value.
My Input has dynamic input arrays.
Example :
$users = [
['name' => 'John' , 'Age' => 25],
['name' => 'Nick' , 'Age' => 28]
]
My requirement is that, if a record is sent along with the request, it has to contain both name and age. At the same time, this whole array is not mandatory.
I can accept
$users = []
Cannot accept
$users = [
['name' => '' , 'Age' => 25],
['name' => 'Nick' , 'Age' => null]
]
Something like that in your Request should work:
public function rules()
{
return [
'users' => 'array', //add 'sometimes' if the array can be null other than empty
'users.*.name' => 'required',
'users.*.Age' => 'required',
]
}
This return false if any of the user is missing name or Age attributes.
I like #Shafeel's solution - Here is another way to go around:
if(count($users >= 1){
foreach($users as $user) {
if(empty($user->name) || empty($user->age) {
return false; //break the loop and return with error message
}
}
}
You can validate an array as an optional or sometimes a validation rule inside a validator.
public function rules()
{
return [
'users' => 'sometimes|array',
'users.*.name' => 'sometimes',
'users.*.Age' => 'sometimes',
]
}
** OR you can**
public function rules()
{
return [
'users' => 'optional|array',
'users.*.name' => 'optional',
'users.*.Age' => 'optional',
]
}
There is a request.How I can validate it? I trying with foreach, but i does not work. Thanks.
The request:
'show_data' => [
0 => [
'buyer_search_property_id' => 1,
'date_of_show' => '2019-01-01',
'comment' => 'Nice flat',
],
1 => [
'buyer_search_property_id' => 2,
'date_of_show' => '2019-01-31',
'comment' => 'Too small',
], etc...
],
I tried this, but it does not work (of course... :))
public function rules()
{
$rules = [];
foreach ($this['show_data'] as $key => $item) {
$rules["show_data[$key]['buyer_search_property_id']"] = 'required';
$rules["show_data[$key]['date_of_show']"] = 'required|date';
$rules["show_data[$key]['comment']"] = 'required';
}
return $rules;
}
This is from laravel documentation:
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',
]);
Read more here
You can validate array in laravel easily like this:
public function rules()
{
return [
"show_data.*.buyer_search_propery_id" => "required",
"show_data.*.date_of_show" => "required|date",
"show_data.*.comment" => "required",
];
}
if you want your method to work, do this:
public function rules()
{
$rules = [];
foreach ($this['show_data'] as $key => $item) {
$rules["show_data.$key.buyer_search_property_id"] = 'required';
$rules["show_data.key.date_of_show"] = 'required|date';
$rules["show_data.$key.comment"] = 'required';
}
return $rules;
}
just remove the inner square brackets and the quotes and add dots to the indices, so change $rules["show_data[$key]['date_of_show']"] to $rules["show_data.$key.date_of_show"]
$data['show_data'] = [
0 => [
'buyer_search_property_id' => 1,
'date_of_show' => '2019-01-01',
'comment' => 'Nice flat',
],
1 => [
'buyer_search_property_id' => 2,
'date_of_show' => '2019-01-31',
'comment' => 'Too small',
],
];
$rules = [
'show_data.*.buyer_search_property_id' => 'required',
'show_data.*.date_of_show' => 'required|date',
'show_data.*.comment' => 'required',
];
$validator = Validator::make($data, $rules);
Note asteriks at rules. With this you don't need a foreach loop. And it looks and feels a lot cleaner.
This is my query:
$productItems = ProductItemResource::collection(ProductItem::where('pd_id', $id)->get());
The output of query is this:
$output = [[
'id' => 1,
'serial' => "XXXXXXAA1",
'pd_item_info' =>[
'id' => 1,
'quantity' => 5,
'product_info' => [
'id' => 1,
'product_name' => 'Keyboard'
],
]
],[
'id' => 2,
'serial' => "XXXXXXAA2",
'pd_item_info' =>[
'id' => 2,
'quantity' => 10,
'product_info' => [
'id' => 2,
'product_name' => 'Monitor'
],
]
]];
This is my condition:
foreach ($output as $productItem) {
return $productItem->pd_item_info->product_info['product_name'];
// IT HAS AN ERROR WHERE I CAN'T ACCESS THE OBJECT OF OBJECT
}
Why I'm getting error accessing object of object when I use resource?
that the result is an array is not an object.
foreach($output as productItem) {
return $productItem['pd_item_info']['product_info']['product_name'];
}
Why you create a new collection?
$productItems = ProductItemResource::collection(ProductItem::where('pd_id', $id)->get());
Result of query already is collection
ProductItem::where('pd_id', $id)->get()