Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

devionti's avatar

Multiple models validation

I have a controller that posts in multiple models at once. Also posts multiple times in one submit request there is a forloop inside the view. The form works the thing is because it uses multiple models I use $data = $request->all(); then I validate after. Most documentation in regards to form validation shows adding rules and messages in regards to one model. I read about form validation and I did it for controllers that only post using one model. Just wondering if there any tips in regards to improving the validation. Like should I use $data = request->validated(…); multiple times?


$data = $request->all();
        $rules = [
            'first_name' => 'nullable',
            'last_name' => 'nullable',
            'email' => 'required|email',
            'attachment_name' => 'nullable',
            'attachment_size' => 'nullable',
            'attachment' => 'required|mimes:pdf|max:2048',
        ];
        $validation = Validator::make($data, $rules, $messages);
        if ($validation->fails()) {
            throw new ValidationException($validation);
        }

        if (!empty($data['experiences'])) {
            if (count($data['experiences']) > 0) {
                foreach ($data['experiences'] as $key => $experience) {
                    $rules = [
                        'experiences.' . $key . '.title' => 'required',
                        'experiences.' . $key . '.location' => 'required',
                        'experiences.' . $key . '.start_date' => 'required',
                        'experiences.' . $key . '.finish_date' => 'required',
                    ];

                    $messages = [
                        'experiences.' . $key . '.title.required' => 'Title field is required for Experience -' . ($key + 1),
                        'experiences.' . $key . '.location.required' => 'Location field is required for Experience -' . ($key + 1),
                        'experiences.' . $key . '.start_date.required' => 'Start Date field is required for Experience -' . ($key + 1),
                        'experiences.' . $key . '.finish_date.required' => 'Finish Date field is required for Experience -' . ($key + 1),
                    ];

                    $validation = Validator::make($data, $rules, $messages);
                    if ($validation->fails()) {
                        throw new ValidationException($validation);
                    }
                    $data['experiences'][$key]['start_date'] = Carbon::createFromFormat('d/m/Y',
                        $experience['start_date']);
                    $data['experiences'][$key]['finish_date'] ? Carbon::createFromFormat('d/m/Y', $education['finish_date'])
                        : null;
                }
            }
        }
    }
0 likes
3 replies
tykus's avatar

Most documentation in regards to form validation shows adding rules and messages in regards to one model

You're missing the point IMHO; we are validating the data in from form; it is irrelevant if this data belongs to one or more models.

What are you doing here, this is not very "Laravel" is it????

if (!empty($data['experiences'])) {
    if (count($data['experiences']) > 0) {
        foreach ($data['experiences'] as $key => $experience) {
            $rules = [//...
devionti's avatar

@tykus In the view there is a repeater so This validation will show only to the relevant key. If you added experience 3 times and you forgot to add something in one of them, this key is there to point to the error.

    <div class="col-sm-12">
                                    <h5>Experiences</h5>
                                        <div data-repeater-list="experiences">
                                            <div data-repeater-item class="inline-form row mx-0 mb-15">
                                                <div class="col-md-6 col-sm-12">
                                                    <label>Title</label>
                                                    <input type="text" name="experiences[title]"
                                                           class="form-control" placeholder="Title"/>
                                                </div>
                                                <div class="col-md-6 col-sm-12">
                                                    <label>Location</label>
                                                    <input type="text" required name="experiences[location]"
                                                           class="form-control" placeholder="Location"/>
                                                </div>
                                                <div class="col-md-6 col-sm-12">
                                                    <label>Start Date</label>
                                                    <input type="text" required name="experiences[start_date]"
                                                           class="form-control" data-provide="datepicker"
                                                           data-date-start-date="0"
                                                           data-date-autoclose="true"
                                                           placeholder="Start Date"/>
                                                </div>
                                                <div class="col-md-6 col-sm-12">
                                                    <label>Finish Date</label>
                                                    <input type="text" required name="experiences[finish_date]"
                                                           data-date-start-date="0"
                                                           data-date-autoclose="true"
                                                           class="form-control" data-provide="datepicker"
                                                           placeholder="Finish Date"/>
                                                </div>
                                                <div class="col-md-6 col-sm-12">
                                                    <label>Description</label>
                                                    <input type="text" name="experiences[description]"
                                                           class="form-control" placeholder="Description"/>
                                                </div>
                                                <div class="col-md-6 col-sm-12 mt-32">
                                                    <button data-repeater-delete type="button" class="btn btn-primary">
                                                        Delete
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                        <div class="col-sm-12">
                                            <input data-repeater-create type="button" class="add-button btn btn-primary"
                                                   value="+ Add Experience"/>
                                        </div>
                                    </div>
                                </div>
tykus's avatar
tykus
Best Answer
Level 104

@devionti there is a wildcard for the array keys

$rules = [
    'first_name' => 'nullable',
    'last_name' => 'nullable',
    'email' => 'required|email',
    'attachment_name' => 'nullable',
    'attachment_size' => 'nullable',
    'attachment' => 'required|mimes:pdf|max:2048',

    'experiences.*.title' => 'required',
    'experiences.*.location' => 'required',
    'experiences.*.start_date' => 'required',
    'experiences.*.finish_date' => 'required',
];
2 likes

Please or to participate in this conversation.