Search code examples
phplaravellaravel-11

Laravel Validation - How can I make Rule::in() allow missing/null values?


I use the Laravel validator to dynamically validate a field like so:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;


                $validator = Validator::make(
                    data: (array)$parent,
                    rules: [
                        'code' => [Rule::in($allowedCodes)],
                    ]
                );

                if ($validator->fails()) { ... }

However, I want to be able to also allow missing/null values.

How can I do this? Adding null in the list of $allowedCodes does not seem to work.

Also, I try to avoid using the string representation of the in rule (that requires concatenating all allowed codes into a string.


Solution

  • To allow for both valid codes and null values in Laravel's Validator, you can modify your rule slightly. Instead of directly adding null to the $allowedCodes array (which doesn't work with Rule::in), you should ensure that null is treated as a valid value by using a conditional rule in your validation.

    According to the example in the documentation (https://laravel.com/docs/11.x/validation#rule-in):

    use Illuminate\Support\Facades\Validator;
    use Illuminate\Validation\Rule;
    
    $validator = Validator::make(
        data: (array)$parent,
        rules: [
            'code' => ['nullable', Rule::in($allowedCodes)],
        ]
    );
    
    if ($validator->fails()) {
        // Handle validation failure
    }
    

    Alternative (using custom validation): If for some reason you need a more custom approach (such as adding more complex validation for null), you can use a custom validation rule (example in the documentation https://laravel.com/docs/11.x/validation#using-closures ):

    $validator = Validator::make(
        data: (array)$parent,
        rules: [
            'code' => [
                'nullable',
                function ($attribute, $value, $fail) use ($allowedCodes) {
                    if (!is_null($value) && !in_array($value, $allowedCodes)) {
                        $fail($attribute.' is invalid.');
                    }
                },
            ],
        ]
    );