Laravel's validation is one of the most straight forward examples of a validation system, it's feature-rich, has a lot of default rules and they contain clear validation messages for each one of those rules.
However there will always be cases where those messages won't suffice, and it can be beneficial to our UX to write clearer and more concise messages, and therefore we'd have to override the defaults.
Overriding the default message
One way is to change the validation message template across the entire system, this can make sense for email
rules for example, as these are generic and are theoritically consistent.
To do that, navigate to your laravel project, and open the file /resources/lang/en/validation.php
, this file contains ALL validation messages in the framework, you'll notice these templates use :variable
in them, so if you want to use these in your validation you'd have to keep them.
Let's take an example, I want to modify the required_if
validation message, by default it looks like this
[
'required_if' => 'The :attribute field is required when :other is :value.'
]
To modify it I can just replace the value, and I can omit some of the variables or all of them and it will be fine, here's an example
[
'required_if' => ':attribute must be set when :other is equal to :value.'
]
as a result, all required_if
rules will use this template when the validation fails.
Overriding messages for a specific request
There are cases when we want to override the message for a specific rule, but we want to keep the default messages as is.
To do that, we have a few options:
When using a form request class
This is the easiest, when we're using a form request for the validations, we can override the messages
method, and in the method we return an associative array where the key represents the rule, and the value represents the message
As an example:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateUserRequest extends FormRequest {
{
public function rules(): array
{
return [
'email' => ['required', 'email'],
];
}
public function messages()
{
return [
'email' => 'This must be a valid email!'
];
}
}
Here when the validation fails for any email
rule, the overridden message will be used.
When using a validator
In this case, we'll be using the same array that we created in the previous example, but we'll directly use it in the Validator::make()
method.
So to cover the same example as above:
<?php
$rules = [
'email' => ['required', 'email'];
];
$messages = [
'email' => 'This must be a valid email!'
];
$validator = Validator::make(request()->all(), $rules, $messages);
if ($validator->fails()) {
return $validator->errors();
}
When using $request->validate()
or $this->validate()
The same rules apply for this method as the Validator
method, so we'll be creating $rules
and $messages
arrays and passing them to the validate()
method.
So to recreate the same example:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UsersController extends Controller
{
public function store(Request $request)
{
$rules = [
'email' => ['required', 'email'];
];
$messages = [
'email' => 'This must be a valid email!'
];
// or $this->validate($request, $rules, $messages);
$request->validate($rules, $messages);
}
}