New exclude_if / exclude_unless validation rules in Laravel 6

Published on

The latest release of Laravel 6 adds two new validation rules: exclude_if and exclude_unless. They are a new type of validation rule that can completely exclude data from the request. These rules were added in PR #30835.

Consider a form with two radio buttons for either approving or rejecting a document. A field for filling in the reason why the document is being rejected appears only when the reject radio button is checked. The following example is of a typical controller method to handle a form like this:

// Post data
{"is_approved": true, "rejection_reason": "some string"}
public function post(Request $request, Document $document)
{
    $data = $request->validate([
        'is_approved' => 'required|bool',
        'rejection_reason' => 'required_if:is_approved,false|string',
    ]);

    // ❌ The rejection reason is present in the validated data
    // $data === ['is_approved' => true, 'rejection_reason' => 'some string']

    // We now have an approved document with a rejection reason
    $document->update($data);
}

Even worse, if in the example above the rejection reason fails one of its validation rules, the user will get an unnecessary error. If only there was a way to exclude it...

Introducing exclude_if and exclude_unless

With the new exclude validation rules, you can validate the example above like this instead:

// Post data
{"is_approved": true, "rejection_reason": "some string"}
public function post(Request $request, Document $document)
{
    $data = $request->validate([
        'is_approved' => 'required|bool',
        'rejection_reason' => 'exclude_if:is_approved,true|required|string',
        // or
        'rejection_reason' => 'exclude_unless:is_approved,false|required|string',
    ]);

    // ✅ We excluded the rejection reason
    // $data === ['is_approved' => true]

    $document->update($data);
}

Now the rejection reason can never appear in the database if the document was not rejected. The field now also won't get validated unless we actually want to store it, preventing possible unnecessary validation errors.