Laravel Project: Build a Task Manager
This Laravel project ties the whole tutorial together. You will build a simple task manager where logged-in users create, complete and delete their own tasks. It uses migrations, Eloquent relationships, a resource controller, validation, Blade and authentication.
Step 1: Create the Project
laravel new tasks
cd tasks
composer require laravel/breeze --dev
php artisan breeze:install blade
php artisan make:model Task -mcrINFO Model [app/Models/Task.php] created successfully. INFO Migration [database/migrations/..._create_tasks_table.php] created successfully. INFO Controller [app/Http/Controllers/TaskController.php] created successfully.
Step 2: Migration and Model
<?php
// migration
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->date('due_on')->nullable();
$table->boolean('done')->default(false);
$table->timestamps();
});
// app/Models/Task.php
class Task extends Model
{
protected $fillable = ['title', 'due_on', 'done'];
protected function casts(): array { return ['due_on' => 'date', 'done' => 'boolean']; }
public function user(): BelongsTo { return $this->belongsTo(User::class); }
}
// app/Models/User.php
public function tasks(): HasMany { return $this->hasMany(Task::class); }$ php artisan migrate 2026_10_31_140000_create_tasks_table ........ 15ms DONE
Step 3: Routes and Controller
<?php
// routes/web.php
Route::middleware('auth')->group(function () {
Route::resource('tasks', TaskController::class)->only(['index', 'store', 'update', 'destroy']);
});
// app/Http/Controllers/TaskController.php
class TaskController extends Controller
{
public function index(Request $request)
{
$tasks = $request->user()->tasks()->orderBy('done')->orderBy('due_on')->get();
return view('tasks.index', compact('tasks'));
}
public function store(Request $request)
{
$data = $request->validate([
'title' => 'required|string|max:150',
'due_on' => 'nullable|date|after_or_equal:today',
]);
$request->user()->tasks()->create($data);
return back()->with('status', 'Task added');
}
public function update(Request $request, Task $task)
{
abort_unless($task->user_id === $request->user()->id, 403);
$task->update(['done' => ! $task->done]);
return back();
}
public function destroy(Request $request, Task $task)
{
abort_unless($task->user_id === $request->user()->id, 403);
$task->delete();
return back()->with('status', 'Task deleted');
}
}GET /tasks tasks.index
POST /tasks tasks.store
PATCH /tasks/{task} tasks.update
DELETE /tasks/{task} tasks.destroyStep 4: The Blade View
{{-- resources/views/tasks/index.blade.php --}}
<x-app-layout>
@if (session('status')) <p>{{ session('status') }}</p> @endif
<form method="POST" action="{{ route('tasks.store') }}">
@csrf
<input name="title" value="{{ old('title') }}" placeholder="New task">
<input type="date" name="due_on">
<button>Add</button>
@error('title') <p>{{ $message }}</p> @enderror
</form>
<ul>
@forelse ($tasks as $task)
<li>
<form method="POST" action="{{ route('tasks.update', $task) }}" style="display:inline">
@csrf @method('PATCH')
<button>{{ $task->done ? 'Undo' : 'Done' }}</button>
</form>
<span @class(['line-through' => $task->done])>{{ $task->title }}</span>
@if ($task->due_on) <small>due {{ $task->due_on->format('M j') }}</small> @endif
<form method="POST" action="{{ route('tasks.destroy', $task) }}" style="display:inline">
@csrf @method('DELETE')
<button>Delete</button>
</form>
</li>
@empty
<li>No tasks yet. Add your first one above.</li>
@endforelse
</ul>
</x-app-layout>Task added [Done] Write Laravel tutorial due Nov 3 [Delete] [Undo] Install Breeze (crossed out) [Delete]
Ideas to Extend the Project
- Move the ownership check into a TaskPolicy and use Gate::authorize
- Add a Form Request class for validation
- Add categories with a belongsToMany relationship
- Send a queued reminder email for tasks due tomorrow using the scheduler
- Expose the tasks as a JSON API protected by Sanctum
- Write feature tests with php artisan test
Frequently asked questions
What is a good first Laravel project?
A CRUD app such as a task manager, blog or notes app. It covers routing, controllers, Eloquent, validation and Blade in one small project.
How do I deploy a Laravel project?
Use a server with PHP and a database, point the web root to the public folder, set .env, run composer install --no-dev, php artisan migrate --force and php artisan optimize. Laravel Forge or Laravel Cloud can automate this.
How do I test my Laravel app?
Write feature tests in tests/Feature using Pest or PHPUnit and run php artisan test. Laravel provides helpers like actingAs() and assertRedirect().