Skip to content
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

Nested validation rules broken for non-wildcard keys #48880

Closed
oprypkhantc opened this issue Nov 1, 2023 · 5 comments
Closed

Nested validation rules broken for non-wildcard keys #48880

oprypkhantc opened this issue Nov 1, 2023 · 5 comments

Comments

@oprypkhantc
Copy link
Contributor

Laravel Version

10.19.0

PHP Version

8.1.9

Database Driver & Version

No response

Description

Hey.

When trying to use NestedRules with a key that's doesn't have a wildcard in it, it throws an error.

use Illuminate\Validation\NestedRules;
use Illuminate\Validation\Validator;

$data = [
	'items' => [
		['discounts' => [['id' => 1], ['id' => 1], ['id' => 2]]],
		['discounts' => [['id' => 1], ['id' => 2]]],
	],
];

$rules = [
	'item' => new NestedRules(function () {
		return ['discounts.*.id' => 'distinct'];
	}),
];

// ErrorException: Undefined array key "item"
//   /app/vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php:131
//   /app/vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php:94
//   /app/vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php:73
//   /app/vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php:51
$v = new Validator(app('translator'), $data, $rules);

$v->passes();

dd($v->errors()->all());

The same exact example but with a wildcard key works:

$rules = [
         // Notice the added ".*" to the "items" key
	'items.*' => new NestedRules(function () {
		return ['discounts.*.id' => 'distinct'];
	}),
];

This use case is not documented, but rule name NestedRules implies it should work for any kind of nested rules and any keys, when in fact it doesn't. It makes sense to be support this use case, given most of the code is already there and the benefit is the same as with wildcard keys - to be able to share validation rules across multiple places.

It looks like the fix should be relatively trivial - ValidationRuleParser::explodeExplicitRule should iterate over rules and "explode" NestedRules rules the same way ValidationRuleParser::explodeWildcardRules does. I can work on a fix if it has a chance to get merged.

Steps To Reproduce

  1. Have a clean setup of Laravel at least 10.19.0
  2. Copy the first example provided and run it
Copy link

github-actions bot commented Nov 1, 2023

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

@oddvalue
Copy link

oddvalue commented Nov 9, 2023

@oprypkhantc I think you just need to add a wildcard to the items rule:

$rules = [
	'items.*' => new NestedRules(function () {
		return ['discounts.*.id' => 'distinct'];
	}),
];

@oprypkhantc
Copy link
Contributor Author

@oddvalue Well yeah, that's the documentation example that works. But in my case I just want to share the rules for a non-array value.

@sonja-turo
Copy link

Not sure if I'm missing something here, but isn't the cause of your issue in your sample code due to you having the key items in your data, but a rule checking item?

@crynobone
Copy link
Member

Hey there,

We're closing this issue because it's inactive, already solved, old, or not relevant anymore. Feel free to open up a new issue if you're still experiencing this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants