Build a CRUD App — Step by StepExtra· 45 min read

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

RuleMeansExample use
requiredMust be presentname
nullableMay be emptydescription
string / integer / numeric / booleanMust be that typeprice → numeric
emailA valid email addressemail
min:n / max:nLength (text) or value (numbers)password → min:8
between:a,bBetween two valuesage → between:18,99
in:a,b,cOne of a fixed liststatus → in:draft,published
unique:table,columnNot already in the databaseemail → unique:users,email
confirmedNeeds a matching <field>_confirmationpassword
image / mimes:jpg,pngAn uploaded file of a typephoto

Combining rules with the pipe

Stack several rules on one field by separating them with | (a pipe). Here is a sign-up example:

Multiple rules per field
$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:

Friendlier messages
$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:

A summary of all validation errors
@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:

Create a Form Request class
php artisan make:request ProductRequest
All the rules live in one place now
// 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:

The controller is now tiny and clean
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?

Answer: confirmed checks that a matching <field>confirmation input (here passwordconfirmation) was submitted and equals the field.

✍️ Practice

  1. Write validation rules for a registration form: name, email (unique), password (min 8, confirmed).
  2. Create a ProductRequest and switch your store() and update() to use it.

🏠 Homework

  1. List five validation rules you would put on a “user profile” form and say why each matters.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →