Laravel `lt` and 'gt' validation rules only if target fields are present

Viewed 3491

I have two integer fields to validate in my request, min_height and max_height, with both being optional but having min_height to be lower than max_height and max_height hanving to be (of course) greater than min_height.

Using the validation rule as follow

'min_height' => ['nullable', 'integer', 'lt:max_height'],
'max_height' => ['nullable', 'integer', 'gt:min_height'],

This of course gives me error when either one is present but not the other, since the lt/gt validation rule check against a null request field.

How can i have lt/gt being checked only if the other field is present? Is there a way to achieve this with built-in validation rules or do i have to implement a custom validator?

UPDATE

Probably i have not been clear enough: my two field are both nullable and independent of each other, so it's ok to receive min_height and not max_height and vice versa: this makes rules like required_with not suitable for my use case.

4 Answers

You can try using required_with conditional rule. For example your condition will

'min_height' => 'required_with:max_height|lt:max_height',
'max_height' => 'required_with:min_height|gt:min_height',

As @vinayak-sarawagi said, there are no built-in solution for this use case, so a custom validation rule have to be implemented to check for the optionally null parameter before actually compare values.

I had the same problem and here is an elegant solution that works and does not require creating a custom rule. Just use plain old PHP. Check if the field you compare to is filled and only then add your validation rule:

'min_height' => [ 
    'nullable',
    'integer', 
     request()->filled('max_height') ? 'lt:max_height' : ''
     ],
'max_height' => [
    'nullable', 
    'integer', 
     request()->filled('min_height') ? 'gt:min_height' : ''
    ],

If you have your rules inside a FormRequest you can use $this->filled('min_height') instead of request()->filled('min_height')

Related