We’ve already learned:
Routes – Handle incoming URLs.
Controllers – Organize logic.
Views & Blade – Show HTML pages.
Request & Validation – Handle and validate forms.
Models & Eloquent ORM – Save data in the database.
Now let’s use these to build a Contact Management CRUD application.
Setting Up the Model & Migration
If you already have the Contact model from the last lesson, you can skip this step.
Otherwise, create it with:
php artisan make:model Contact -m
Update the migration in database/migrations/xxxx_xx_xx_create_contacts_table.php:
public function up(): void
{
Schema::create('contacts', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});
}
Run:
php artisan migrate
Add this code to the Contact model class (located at Models/Contact.php) if it does not already exist.
class Contact extends Model
{
protected $fillable = ['name', 'email'];
}
Creating the Controller
We’ll use a Resource Controller for all CRUD actions:
php artisan make:controller ContactController --resource
This creates ContactController.php with methods for all CRUD actions.
Defining Routes
In routes/web.php:
use App\Http\Controllers\ContactController;
Route::resource('contacts', ContactController::class);
This single line creates all routes:
| Method | URL | Action |
|---|---|---|
| GET | /contacts | index |
| GET | /contacts/create | create |
| POST | /contacts | store |
| GET | /contacts/{id} | show |
| GET | /contacts/{id}/edit | edit |
| PUT | /contacts/{id} | update |
| DELETE | /contacts/{id} | destroy |
Implementing CRUD Logic in the Controller
In app/Http/Controllers/ContactController.php:
<?php
namespace App\Http\Controllers;
use App\Models\Contact;
use Illuminate\Http\Request;
class ContactController extends Controller
{
public function index()
{
$contacts = Contact::all();
return view('contacts.index', compact('contacts'));
}
public function create()
{
return view('contacts.create');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|min:3',
'email' => 'required|email'
]);
Contact::create($request->only(['name', 'email']));
return redirect()->route('contacts.index')->with('success', 'Contact created successfully.');
}
public function edit(Contact $contact)
{
$contact = Contact::findOrFail($id);
return view('contacts.edit', compact('contact'));
}
public function update(Request $request, Contact $contact)
{
$request->validate([
'name' => 'required|min:3',
'email' => 'required|email'
]);
$contact = Contact::findOrFail($id);
$contact->update($request->only(['name', 'email']));
return redirect()->route('contacts.index')->with('success', 'Contact updated successfully.');
}
public function destroy(Contact $contact)
{
$contact->delete();
return redirect()->route('contacts.index')->with('success', 'Contact deleted successfully.');
}
}
Creating the Views
i) Contact List – resources/views/contacts/index.blade.php
@extends('layouts.main')
@section('title', 'Contacts')
@section('content')
<h2>Contact List</h2>
@if(session('success'))
<p style="color:green;">{{ session('success') }}</p>
@endif
<a href="{{ route('contacts.create') }}">Add Contact</a>
<ul>
@foreach($contacts as $contact)
<li>
{{ $contact->name }} - {{ $contact->email }}
<a href="{{ route('contacts.edit', $contact->id) }}">Edit</a>
<form action="{{ route('contacts.destroy', $contact->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit" onclick="return confirm('Delete this contact?')">Delete</button>
</form>
</li>
@endforeach
</ul>
@endsection
ii) Add Contact – resources/views/contacts/create.blade.php
@extends('layouts.main')
@section('title', 'Add Contact')
@section('content')
<h2>Add New Contact</h2>
<form action="{{ route('contacts.store') }}" method="POST">
@csrf
<label>Name:</label>
<input type="text" name="name" value="{{ old('name') }}">
@error('name') <p style="color:red;">{{ $message }}</p> @enderror
<label>Email:</label>
<input type="email" name="email" value="{{ old('email') }}">
@error('email') <p style="color:red;">{{ $message }}</p> @enderror
<button type="submit">Save</button>
</form>
@endsection
iii) Edit Contact – resources/views/contacts/edit.blade.php
@extends('layouts.main')
@section('title', 'Edit Contact')
@section('content')
<h2>Edit Contact</h2>
<form action="{{ route('contacts.update', $contact->id) }}" method="POST">
@csrf
@method('PUT')
<label>Name:</label>
<input type="text" name="name" value="{{ old('name', $contact->name) }}">
@error('name') <p style="color:red;">{{ $message }}</p> @enderror
<label>Email:</label>
<input type="email" name="email" value="{{ old('email', $contact->email) }}">
@error('email') <p style="color:red;">{{ $message }}</p> @enderror
<button type="submit">Update</button>
</form>
@endsection
Summary of the CRUD Flow
- Create →
/contacts/create→ store in DB. - Read →
/contacts→ list all contacts. - Update →
/contacts/{id}/edit→ save changes. - Delete →
/contacts/{id}→ remove from DB.
Conclusion:
You now have a complete Laravel CRUD application.

