'How to override the message of the custom validation rule in Laravel?

I am developing a Laravel application. What I am doing in my application is that I am trying to override the custom validation rule message.

I have validation rules like this in the request class:

[
    'name'=> [ 'required' ],
    'age' => [ 'required', new OverAge() ],
];

Normally, we override the error message of the rules like this:

return [
    'title.required' => 'A title is required',
    'body.required'  => 'A message is required',
];

But how can I do that to the custom validation rule class?



Solution 1:[1]

You cannot simply overwrite it with the custom messages of the request. If you take a look at the Validator class:

/**
 * Validate an attribute using a custom rule object.
 *
 * @param  string  $attribute
 * @param  mixed  $value
 * @param  \Illuminate\Contracts\Validation\Rule  $rule
 * @return void
 */
protected function validateUsingCustomRule($attribute, $value, $rule)
{
    if (! $rule->passes($attribute, $value)) {
        $this->failedRules[$attribute][get_class($rule)] = [];

        $this->messages->add($attribute, $this->makeReplacements(
            $rule->message(), $attribute, get_class($rule), []
        ));
    }
}

As you can see, it's simply adding the $rule->message() directly to the message bag.

However, you can add a parameter for the message in your custom rule's class:

public function __construct(string $message = null)
{
    $this->message = $message;
}

Then in your message function:

public function message()
{
    return $this->message ?: 'Default message';
}

And finally in your rules:

'age' => ['required', new OverAge('Overwritten message')];

Solution 2:[2]

Working with Laravel 9, overriding the message is supported, but you must supply the FQDN for the validation class. So your OverAge custom message may look like this:

return [
    'age.required' => 'An age is required',
    'age.App\\Rules\\OverAge'  => 'The age must be less than 65',
];

You may also want to support place-holders for the message, so the 65 can be replaced by something like :max-age. Many ways to do that are published, none of which look particularly clean.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2