Suppose we have the following form data:
{age: 15, father: "John Doe"}
We want to have some complex logic behind validating the father
field based on other data for the same item (for this example, we want to validate that father has at least 5 characters when age < 18).
This could be done like that:
Standard validation rules: ['age': 'required|integer']
$validator->sometimes('father', 'required|min:5', function($data) {
return $data['age'] < 18;
});
Now, we want to have the same kind of thing with a list of items. So now, we have the following form data:
[
{age: 25, },
{age: 15, father: "John Doe"},
{age: 40, },
]
Common validation rule now looks like that:
['items.*.age': 'required|integer']
My issue is now to easily express the sometimes
rule for each item's father
field which will depend on the item's age
field.
$validator->sometimes('items.*.father', 'required|min:5', function($data) {
// Does not work anymore: return $data['age'] < 18;
// Any way to know which item we are dealing with here?
});
One way I could think of is to loop over the items in a validator after
callback. But that does not seem very elegant :(
Couldn't get sometimes()
to work in a way you need. sometimes()
doesn't "loop" over array items, it gets called a single time.
I came up with an alternative approach, which isn't perfect, but maybe you'll find it useful.
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
Validator::extend('father_required_if_child', function ($attribute, $value, $parameters, $validator) {
$childValidator = Validator::make($value, [
'age' => 'required|integer'
]);
$childValidator->sometimes('father', 'required|min:5', function($data) {
return is_numeric($data['age']) && $data['age'] < 18;
});
if (!$childValidator->passes()) {
return false;
}
return true;
// Issue: since we are returning a single boolean for three/four validation rules, the error message might
// be too generic.
// We could also ditch $childValidator and use basic PHP logic instead.
});
return [
'items.*' => 'father_required_if_child'
];
}
Curious to learn how this could be improved.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With