Back to Blog
Lesson 39 of the Laravel Fundamentals: From Zero to Your First App course
LaravelJune 25, 20263 min read

Task Manager: Adding Status and Priorities in Laravel

Enhance your Task Manager with status and priority fields. Learn how to evolve your database schema, update your Blade UI, and implement state toggling.

LaravelDatabaseUXCRUDMigrationsphpbackend

Previously in this course, we finished Task Manager: Completing CRUD Functionality in Laravel. Now, it’s time to move beyond basic text fields. A real-world Task Manager needs to track progress and urgency, so we’ll add status and priority columns to our database and expose them in our UI.

Evolving the Database Schema

When your application grows, your database needs to follow suit. We've already covered the basics of Understanding Database Migrations, so we’ll jump straight into creating a migration to modify our existing tasks table.

Run this command in your terminal:

Bash
php artisan make:migration add_status_and_priority_to_tasks_table --table=tasks

Open the generated file in database/migrations. We will add two columns: status (boolean, default false) and priority (integer, default 1).

PHP
public function up()
{
    Schema::table('tasks', function (Blueprint $table) {
        $table->boolean('is_completed')->default(false);
        $table->unsignedInteger('priority')->default(1);
    });
}

public function down()
{
    Schema::table('tasks', function (Blueprint $table) {
        $table->dropColumn(['is_completed', 'priority']);
    });
}

Run php artisan migrate to apply these changes. Ensure you update your Task model's $fillable property to allow mass assignment for these new fields, as we learned in Preventing Mass Assignment in Laravel.

Implementing Status Toggling

To improve the UX, we want to allow users to toggle a task's status directly from the list view without navigating to an edit screen. We’ll add a simple route and controller method to handle this.

In your routes/web.php:

PHP
Route::patch('/tasks/{task}/toggle', [TasksController::class, 'toggle'])->name('tasks.toggle');

In your TasksController, implement the toggle logic:

PHP
public function toggle(Task $task)
{
    $task->update([
        'is_completed' => !$task->is_completed
    ]);

    return back()->with('success', 'Task status updated!');
}

Updating the UI

Now, we update our Blade view. Since we have a master layout, we can inject a small form into our list view to trigger the patch request.

HTML
@foreach ($tasks as $task)
    style="color:#808080"><style="color:#4EC9B0">div class="task-item">
        style="color:#808080"><style="color:#4EC9B0">form action="{{ route('tasks.toggle', $task) }}" method="POST">
            @csrf
            @method('PATCH')
            style="color:#808080"><style="color:#4EC9B0">button type="submit">
                {{ $task->is_completed ? 'Undo' : 'Complete' }}
            style="color:#808080"></style="color:#4EC9B0">button>
        style="color:#808080"></style="color:#4EC9B0">form>
        style="color:#808080"><style="color:#4EC9B0">span>{{ $task->title }} (Priority: {{ $task->priority }})style="color:#808080"></style="color:#4EC9B0">span>
    style="color:#808080"></style="color:#4EC9B0">div>
@endforeach

Hands-on Exercise

  1. Add Validation: Update your FormRequest to ensure the priority field is an integer between 1 and 3.
  2. Dynamic Styling: In your Blade template, add a CSS class (e.g., line-through) to the task title if $task->is_completed is true.
  3. Sorting: Modify your index query in the TasksController to sort tasks by priority descending, then by created_at descending.

Common Pitfalls

  • Mass Assignment: Forgetting to update the $fillable array in the model will cause the new fields to remain unchanged even if the request is successful.
  • Migration Order: If you try to run logic on a column before the migration has finished, you'll encounter "Column not found" errors. Always run migrations before updating your code logic.
  • CSRF tokens: Since you are using a form to trigger the toggle, never forget the @csrf directive, or you will receive a 419 error.

Recap

We successfully evolved our Task Manager by adding database columns and providing a seamless toggle mechanism. By leveraging migrations and simple controller actions, we've made the application more functional for the end user. Database changes are a natural part of the development lifecycle, and mastering these incremental updates is key to building maintainable software.

Up next: We will learn about Introduction to Artisan Commands to automate repetitive tasks and gain deeper insights into our application.

Similar Posts