ideas
ideas copied to clipboard
Get only validated data when validating arrays
Hello,
I would like to discuss one of the issues that I often have when validating arrays. Let's say I have this validation:
return [
'source' => 'required',
'target' => 'required',
'paths' => 'required|array',
'paths.*.from' => 'required',
'paths.*.to' => 'required',
];
If I then send this data:
{
"source": "foo",
"target": "bar"
"paths": [
{
"id": 12345,
"from": "/",
"to": "/test"
}
]
}
And call $request->validated(), I expect to only get the data
array:3 [
"source" => "foo"
"target" => "bar"
"paths" => array:1 [
0 => array:3 [
"from" => "/"
"to" => "/test"
]
]
]
What I actually get is:
array:3 [
"source" => "foo"
"target" => "bar"
"paths" => array:1 [
0 => array:3 [
"id" => "12345"
"from" => "/"
"to" => "/test"
]
]
]
Problem: Notice the paths[0].id. This prevents me from just doing $model->relation()->createMany($validated['paths'])
, because 'id' is not a field I expect to be in that array. This is only an issue if I have $guarded = []
on my model though, but I do have it on most of my models. I understand why this is there, because technically I validated the 'paths' attribute, so it just adds the whole thing to the validated array, and then also does paths..from, and paths..to.
Possible solution: I was having a look, at the validated
method in the validator class, and looks like we could quickly fix this with modifying the check https://github.com/laravel/framework/blob/5.8/src/Illuminate/Validation/Validator.php#L341 here with if ($value !== $missingValue && ! $this->hasRule($key, ['Array'])) {
which would mean that if it has an array rule, it would not set that specific field, and it would rely on validations like paths.*.from
, paths.*.to
.
This also means, that if we only validate that attribute to be an array, and we do not validate each child attribute, this would not work and it would not be in $validated array, which might not necessarily be what other people expect, but the way I work, this would be perfect.
The only other solution I can think of is to change how validated method works and do checks recursively on each array attribute..
I would like to get your opinion on this? Is this something worth changing?
same problem
I have this issue too, I'd like to use Model::create($request->validated());
but since I use MongoDB that could become a problem.
same issue here...
same
Dump.
The problem is that validation explicitly says that we want the array so it's validated. The only real solution would be to have a rule which can explicitly exclude it from the validated data. Sadly currently the closest one is the exclude_if rule but that removes the whole array with all child elements.