-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[8.x] Add array_keys validation rule #40720
Conversation
…s all the required entries
I'm curious if we need any additional functionality in the framework for this. It seems you could do (note the array unpacking): return [
'name' => 'required',
'description' => 'required',
'days' => 'bail|array',
...BusinessHourDay::sameCompany()->get()->flatMap(function ($day) {
return [
'days.'.$day->day.'.start_time' => 'required',
'days.'.$day->day.'.end_time' => 'required',
];
}),
]; |
My intended approach here is to handle the times when you might have a some simple validation requirements, like just making sure it has some value using the The approach you have suggested works nicely too, and it is definitely a pattern I'd reach for. I just really like the simplicity of a simple array in the form request validator rather than having to build one up. I'd see the pattern you proposed being something I would more likely reach for if I had some admin interface to generate a dynamic form, where part of that generation was to also specify which validation rules would be used to validate it. I could then dynamically generate the rules to apply to each element in the array. Something like: return [
'questions' => 'bail|array',
...$questionnaire->flatMap(function ($question) {
return [
'question.'.$question->slug => $question->rules,
];
}),
]; If you don't feel it's a good fit, happy to close though :) |
I think I'm a having a bit of a hard time following the rule. Can you give another example of using it - you also use
Can you give an example of this? Ideally without any loops - just hard-coded strings to make it very clear. |
Apologies, it should be I am just going to cook my kids dinner, and then I will write up a clearer example for you to review :) |
If you had an array of questions which you wanted to be asked in a form, you might have something like this: $questions = [
'favourite_color' => 'What is your favorite color?',
'favourite_animal' => 'What is your favorite animal?',
'maiden_name' => 'What is your Mother\'s maiden name?',
'favorite_php_framework' => 'What is your favorite PHP framework?',
]; (This would likely be database driven, or a static array on a model, but the method of which we get it is not really relevant to this.) You could use these to generate a form in a blade file using the key as the input name in an array. @foreach($questions as $question => $key)
<input type="text" name="questions[{{ $key }}] value="{{ old('questions.' . $key) }} ">
@endforeach When it comes to validation, with these, I don't have to care much about the content, only that the user has answered something for them. I would build a rule set in a request validator by looping through the array which would end up looking something like this: public function rules()
{
return [
'questions' => 'array',
'questions.favorite_color' => 'required',
'questions.favourite_animal' => 'required',
'questions.maiden_name' => 'required',
'questions.favorite_php_framework' => 'required',
];
} The rules are the same, and I would have had to flatMap or some other form of loop to build up this rule set. Whereas my approach with the contains_all would be to have a rule set looking like this: public function rules()
{
return [
'questions' => [
'array',
'contains_all:favorite_color,favorite_animal,maiden_name,favorite_php_framework',
],
'questions.*' => 'required',
];
} The contents of the My belief here is this approach is easier when you are trying to keep validation really simple. |
Gotcha. I wonder if something like |
I feel like array_keys would make sense. I had it like this so the behaviour could be applied to a string as well, as most other rules seem to work across data types, but I am not sold on my string implementation. I feel pulling this back to just work with arrays seems like a sensible move. |
I have pushed some new commits to rename the rule to |
@Drewdan @taylorotwell just to make sure you have not forgotten that the “array” rule can actually already take in parameters and if I am remembering correctly already check for precedence of keys in the array? Could it be that the array rule could be helpful in this case as well, sense you already know the specific keys? |
@morloderex - as I understand, the array validation method accepts a list of valid keys, but this does not validate that they are present, it only serves to prevent unacceptable keys being passed through. This rule differs in that it validates all keys are present in the array. Ideally, you would use these in tandem with each other. |
Renamed to |
@morloderex ... @Drewdan is correct that |
@taylorotwell renaming to |
I have recently been finding it more common to have to validate that certain items are available in an array. However, the items that are required are usually dynamically driven and then stored as JSON in a DB column.
A really simple example of this might be shifts for a team. Each team has working days which are pre-defined and stored in a database. There is then a dynamically generated form which asks for the shift times for these days.
The required data for each shift would be the same, a start time and an end time and would be required. Typically, to validate this dynamic data, you might do something such as:
This allows us to validate the days that the user has configured in the database are present in the dynamically generated form.
This proposed change would allow this instead:
This would simplify the validation in the cases where mapping a list of validation rules, which would have the same rules for each entry, but we still want to assert that all the required data was present.
The rule could also be applied to a string field to make sure a part or parts of it given match a particular structure, for example, a form where you might enter an invoice "number" something like "INV:12345-WEB"
Would be grateful for any feedback or thought you have on this :)
Thanks guys.