skip to Main Content

I am doing FormRequest validation. I am using the array rule to ensure that only specified keys are allowed in the validated array. For example:

$rules = [
  'example' => ['array:something,another'],
];

However, if this rule encounters an array key that isn’t in that whitelist the error message I get isn’t very descriptive:

The :attribute field must be an array.

This message doesn’t reference the incorrect array key at all, making it hard for the end user to work out what they did wrong.

Can I improve this error message such that it highlights the fact that an incorrect key has been passed? Something like a custom validation message of:

The :key key is not valid for the :attribute field.

I would have thought that this has been asked before but my Google-fu clearly isn’t strong today! Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    One option is to return a custom validation error message that highlights the keys that are required for that particular field attribute and rule. As this is a form request you would do this like so:

    class MyRequest extends FormRequest
    {
        public function messages(): array
        {
            return [
                'example.array' => 'The :attribute field must be an array with keys something and/or another.',
            ];
        }
    }
    

    This isn't very nice though, as it doesn't tell the user what the error is (is it that the field isn't an array, or that they key is wrong, and which key would that be?). It also requires the message to be hardcoded.


  2. A better solution is a custom validation rule that behaves like the normal array rule, but gives a more sensible error message.

    Use it like:

    use AppRulesArrayWith;
    
    $rules = [new ArrayWith('something,another')];
    

    And the rule itself would look like:

    namespace AppRules;
    
    use Closure;
    use IlluminateContractsValidationValidationRule;
    
    class ArrayWith implements ValidationRule
    {
        public array $keys;
    
        public function __construct(string $keys)
        {
            $this->keys = explode(',', $keys);
        }
    
        public function validate(string $attribute, mixed $value, Closure $fail): void
        {
            if (!is_array($value)) {
                $fail('The '.$attribute.' field must be an array.');
            }
            foreach (array_keys($value) as $key) {
                if (!in_array($key, $this->keys)) {
                    $fail('The '.$key.' key is not valid for the '.$attribute.' field.');
                }
            }
        }
    }
    

    It still feels astonishing that this isn’t the default behaviour, to be honest.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search