Validation, Done Properly
Master Laravel validation — the rules you’ll use most, custom messages, showing all errors, and clean Form Requests.
What you will learn
- Use the most common validation rules confidently
- Write custom error messages
- Move rules into a Form Request for tidy controllers
You already validated — now master it
You have used $request->validate([...]) for name and price. Here is how to validate anything properly, so your forms are bullet-proof. Validation is the single most important habit for a safe app.
The rules you will use most
| Rule | Means | Example use |
|---|---|---|
required | Must be present | name |
nullable | May be empty | description |
string / integer / numeric / boolean | Must be that type | price → numeric |
email | A valid email address | |
min:n / max:n | Length (text) or value (numbers) | password → min:8 |
between:a,b | Between two values | age → between:18,99 |
in:a,b,c | One of a fixed list | status → in:draft,published |
unique:table,column | Not already in the database | email → unique:users,email |
confirmed | Needs a matching <field>_confirmation | password |
image / mimes:jpg,png | An uploaded file of a type | photo |
Combining rules with the pipe
Stack several rules on one field by separating them with | (a pipe). Here is a sign-up example:
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8|confirmed',
]);Reading them: email must be present, a valid email, and not already in the users table’s email column. password must be present, at least 8 characters, and confirmed — meaning the form also has a password_confirmation box that must match.
Note: The confirmed rule is why login/signup forms have a “Confirm password” box named exactly password_confirmation — Laravel checks the two match for you.
Custom error messages
The default messages are clear, but you can write your own by passing a second array — keyed by field.rule:
$request->validate([
'name' => 'required',
'price' => 'required|numeric',
], [
'name.required' => 'Please enter a product name.',
'price.numeric' => 'Price must be a number, like 499.',
]);The key 'name.required' means “the message for when the name field breaks the required rule”.
Showing every error in one place
Besides the per-field @error we used, you can list all errors together at the top of a form:
@if ($errors->any())
<ul style="color:red">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif$errors->any() is true if anything failed; $errors->all() is the full list of messages. $errors is available in every view automatically after a failed validation.
Tidy controllers with a Form Request
Repeating the same rules in store() and update() is messy. Move them into a dedicated Form Request class — one home for the rules:
php artisan make:request ProductRequest// app/Http/Requests/ProductRequest.php
public function authorize(): bool
{
return true; // anyone may submit (add real checks later)
}
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
'description' => 'nullable|string',
];
}Then in the controller, type-hint ProductRequest instead of Request. Laravel runs the validation automatically before your method even starts:
public function store(ProductRequest $request)
{
Product::create($request->validated());
return redirect()->route('products.index')->with('success', 'Product added!');
}If validation fails, Laravel redirects back with the errors automatically (same as before). If it passes, $request->validated() gives you the clean data. Now store() and update() can share the same rules with zero duplication. (See the “Form Request Validation” lesson for more.)
Tip: Rule of thumb: validate every piece of user input, on the server, every time. It is the front door to your app — keep it locked.
Q. What does the confirmed rule on a password field require?
✍️ Practice
- Write validation rules for a registration form: name, email (unique), password (min 8, confirmed).
- Create a
ProductRequestand switch yourstore()andupdate()to use it.
🏠 Homework
- List five validation rules you would put on a “user profile” form and say why each matters.