Validate only and atleast one field is required out of two fields in Laravel

Harish Toshniwal • July 24, 2018

original laravel

Let's consider the following example: Our form has 2 fields video (a file input) & videourl (a text field). Our users can either upload a video directly or submit an URL to a remote video file. Now, let's see how we would validate that atleast the user has either uploaded a video or given a video url and we would also validate that the user hasn't submitted both.

First, let's have a look at the final code from our form request class to achieve the solution for the above problem followed by the explanation of the code written for it:

public function rules()
{
    return [
        'video' => [
            'bail',
            function ($attribute, $value, $fail) {
                if (request()->has($attribute) === request()->filled('videourl')) {
                    return $fail('Only 1 of the two is allowed');
                }
            },
            'file',
            'mimetypes:video/avi,video/mpeg,video/quicktime,video/mp4,video/x-mpegURL,video/MP2T,video/x-flv'
        ],
        'videourl' => [
            'required_without:video',
            'nullable',
            'active_url',
        ],
    ];
}

We use the closure based custom validation approach because we only need this custom rule for a single form and a particular request. If you want to use it for multiple forms or requests feel free to abstract it to a Rule class.

We don't want both fields to be either empty or filled, so we check that both:

request()->has($attribute)

&

request()->filled('videourl')

return different bool values. We don't want both these conditions to be either true or false, we want only one of them to be true and the other to be false.

If you are aware of other possible & more better solutions, you can correct me with those on twitter, would love to learn and implement them.