Laravel sometimes validation on arrays Laravel sometimes validation on arrays laravel laravel

Laravel sometimes validation on arrays


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.


The shortest approach I could get to work is this:

"items" => "required|array","items.*.age" => "required|integer","items.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"

Anytime a father is needed for that person, it should be having at least 5 characters. A father is needed when the person's age is below 18.

required_if works with multiple equations separated with commas. Therefore I wrote 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 as implode(',',range(0,18)) to get that part.

The test setup I've used:

Controller (used HomeController)

function posttest(Request $request) {    $validator = Validator::make($request->all(), [        "object" => "required|array",        "object.*.age" => "required|integer",        "object.*.father" => "required_if:object.*.age,".implode(",",range(0,18))."|min:5"    ]);    if($validator->fails()){        dd($validator->errors());    }}

View (test.blade.php)

@extends('layouts.app')@section('content')<form action="{{URL::to("/posttest")}}" method="POST">@csrf<input type="number" name="object[0][age]" value="12"><input type="text" name="object[0][father]" value="John"><input type="number" name="object[1][age]" value="15"><input type="text" name="object[1][father]" value="John Doe"><input type="number" name="object[2][age]" value="17"><input type="submit" value="gönder"></form>@endsection

Routes

Route::view("/test", "test");Route::post('/posttest', "HomeController@posttest");