-
Notifications
You must be signed in to change notification settings - Fork 11.3k
[9.x] Patch nested array validation rule regression bug #43897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[9.x] Patch nested array validation rule regression bug #43897
Conversation
Awesome Steve. Thanks so much for adding the additional tests as well! 😀 |
Hi @stevebauman. I've updated to 9.27 version and getting error for this rule. My rule:
|
Hi @siarheipashkevich -- as shown in the above PR, you can no longer nest one or many $rules = [
'conditions.*.items.*.item_id' => ['required', 'integer', Rule::forEach('...')], // <-- Will not work.
]; You must refactor the validation rule like so by returning all your validation rules inside of the $promotionItemIdRule = Rule::forEach(function (mixed $value, string $attribute, array $data) use (
$conditionItemIds,
) {
$type = Arr::get($data, Str::replaceLast('.item_id', '.item_type', $attribute));
return ['required', 'integer', Rule::in($conditionItemIds->get($type, []))]; // <-- All rules returned here.
});
// ...
$rules = [
'conditions.*.items.*.item_id' => $promotionItemIdRule,
]; |
@stevebauman thank you so much. |
Happy to help @siarheipashkevich. Also you may be able to use something like this to clean it up a bit (correct me if I'm wrong): $rules = [
'conditions.*.items' => ['required', 'array'],
'conditions.*.items.*.item_id' => ['required', 'integer'],
'conditions.*.items.*.item_type' => ['required', 'string'],
'conditions.*.items.*' => Rule::forEach(function ($value) use ($conditionItemIds) {
return [
'item_id' => Rule::in($conditionItemIds->get($value['item_type'], [])),
'item_type' => Rule::in(PromotionItemType::all()),
];
}),
]; |
@stevebauman in your example the rules will be combined? |
@siarheipashkevich I'm not sure what you mean, can you elaborate? |
@stevebauman in your example we will have the next rules:
because |
@siarheipashkevich The rules will not be merged. They will be evaluated individually. |
Closes #43779
Closes #43751
Related #43192
Related #40924
This PR resolves a regression bug that I introduced in
9.x
in theRule::forEach()
validation feature, where nested array validation rules can no longer be used, due to flattening them via anArr::flatten($rules)
.For example, this can no longer be done, whereas it used to work in prior versions of Laravel:
Arr::flatten()
was used to be able to determine if a ruleset contains aNestedRules
instance, and allowed validation rules to be infinitely nested, as they would be flattened before being parsed:framework/src/Illuminate/Validation/ValidationRuleParser.php
Lines 154 to 155 in 2a1a55c
This PR will break the below (however unlikely) implementation for developers -- but will resolve the regression bug, while keeping the
Rule::forEach
feature:Developers will have instead have to use a single
Rule::forEach()
(non-nested), as this will no longer be supported:I've added test to ensure we have some coverage over the nested array rule feature so regression will not occur again in the future.
Thanks so much for your time, and I apologize for this issue that has caused grief for devs upgrading to 9.x ❤️