CRUD Step 3: Add a Product + Validation
Build the “add new” form, save it safely, and validate the input — showing friendly errors when something is wrong.
What you will learn
- Build a form that submits to store()
- Validate input on the server with clear rules
- Show validation errors and keep the user’s typed values
Create = show a form, then save it
“Create” is two methods working together: create() shows an empty form, and store() receives the submitted data, validates it, and saves it. Validation is the important new skill here — never trust what a user types.
The create() method
public function create()
{
return view('products.create');
}That is all create() does — return the empty form view. The real work, validating and saving, happens in store() further down.
The form (create.blade.php)
This form sends its data to the store route. It includes @csrf — a hidden security token Laravel requires on every form, or it rejects the request. It also shows an error message under each field and remembers what the user typed:
<h1>Add Product</h1>
<form method="POST" action="{{ route('products.store') }}">
@csrf
<label>Name</label>
<input type="text" name="name" value="{{ old('name') }}">
@error('name') <p style="color:red">{{ $message }}</p> @enderror
<label>Price</label>
<input type="text" name="price" value="{{ old('price') }}">
@error('price') <p style="color:red">{{ $message }}</p> @enderror
<label>Description</label>
<textarea name="description">{{ old('description') }}</textarea>
@error('description') <p style="color:red">{{ $message }}</p> @enderror
<button type="submit">Save Product</button>
</form>The key parts: method="POST" + action="{{ route('products.store') }}" send the form to store(). @csrf adds the required security token. Each name="..." must match the field name we validate and save. @error('name') ... @enderror shows a red message only if that field failed validation, and value="{{ old('name') }}" refills the box with what the user typed so they do not start over.
The store() method — validate, then save
This is the heart of it. store() does two jobs in order: validate the input, then save it.
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'price' => 'required|numeric|min:0',
'description' => 'nullable|string',
]);
Product::create($validated);
return redirect()->route('products.index')
->with('success', 'Product added!');
}Line by line — this is the most important code in the lesson:
$request->validate([...])checks each field against its rules.- If any rule fails, Laravel automatically stops, sends the user back to the form, attaches the error messages, and keeps their old input — you write zero code for that.
- If all rules pass,
validate()returns only the clean, checked data as$validated. Product::create($validated)saves that clean data as a new row.redirect()->route('products.index')->with('success', '...')sends the user to the list with a one-time success message.
What each rule means
| Rule | Means |
|---|---|
required | Must not be empty |
string | Must be text |
max:255 | At most 255 characters |
numeric | Must be a number |
min:0 | Number not below 0 (no negative price) |
nullable | Allowed to be empty |
Note: Output: Submit the form empty → you are sent straight back, with “The name field is required.” and “The price field is required.” shown in red, and anything you did type is still in the boxes. Submit valid data → the product is saved and you land on the list with “Product added!”.
Watch out: ALWAYS validate on the server with $request->validate. The HTML required attribute is only a hint — a user can bypass it. Server-side validation is your real guard, and it is what protects your database.
Tip: Keep four names in sync for every field: the input name="price", the validation key 'price' => ..., the model $fillable entry, and old('price'). Same word everywhere.
Q. When $request->validate() finds an invalid field, what does Laravel do automatically?
✍️ Practice
- Add a
stockfield to the form, validate it withrequired|integer|min:0, and add it to$fillable. - Submit the form empty and watch the red messages appear; then submit valid data and see it saved.
🏠 Homework
- Explain why server-side validation is essential even when your form already has the HTML
requiredattribute.