phparrayslaravelvalidationrules

How to access nested item in Rule::requiredIf() validation


I'm trying to validate an array inside a custom Request. The rule evaluates to required if two conditions are met:

  1. attribute3 is true
  2. another column from the same array is true

Here's what I'm doing:

public function rules()
{
    return [
        'attribute1' => 'required',
        'attribute2' => 'required',
        'attribute3' => 'required',
        ...
        'attribute10.*.column3' => Rule::requiredIf(fn() => $this->attribute3), // <- array
        'attribute10.*.column4' => Rule::requiredIf(fn() => $this->attribute3), // <- array
        'attribute10.*.column5' => Rule::requiredIf(fn() => $this->attribute3), // <- array
    ];
}

What I really need is this:

'attribute10.*.column4' => Rule::requiredIf(fn($item <- magically hint this currently looped item) => $this->attribute3 && $item->column2 <- so I can use it like this), // <- array

Solution

  • Assuming the incoming request has a structure like the following:

    [
        'attribute1' => 1,
        'attribute2' => 0,
        'attribute3' => 1,
        'attribute10' => [
            [
                'column1' => 1,
                'column2' => 1,
                'column3' => 0,
            ],
            [
                'column1' => 0,
                'column2' => 1,
                'column3' => 0,
            ],
        ],
    ]
    

    You can set the rules array to a variable, and then loop over the attribute10 field array elements and merge each rule on the rules variable. Then you'll have access to the other elements on the nested array.
    Ie:

    public function rules()
    {
        $rules = [
            'attribute1' => 'required',
            'attribute2' => 'required',
            'attribute3' => 'required',
        ];
        foreach($this->attribute10 as $key => $item) {
            array_merge($rules, [
                'attribute10.'.$key.'.column2' => Rule::requiredIf($this->attribute3 && $item['column1']),
                'attribute10.'.$key.'.column3' => Rule::requiredIf($this->attribute3 && $item['column2']),
                //...
            ]);
        }
        return $rules;
    }