Lesson 2
Database Migrations in Laravel
Database Migrations in Laravel

Welcome to a crucial step in enhancing your Laravel ToDo application! In this lesson, we will focus on database migrations, a fundamental feature that ensures your database schema is consistent and manageable. Building on our previous lesson, in which you learned to integrate a database within your Laravel app, we'll now explore how to maintain and evolve your database structure effectively.

Database migrations are an integral part of the development process, especially in collaborative environments where database changes need to be tracked and implemented seamlessly.

What You'll Learn

In this lesson, you will discover how to create, manage, and apply database migrations in Laravel. Migrations are essential because they allow developers to version-control database changes and easily share them within a team.

You might have noticed, that we used a strange file in the previous lesson located in the database/migrations directory. This file is a migration file, and it contains instructions for creating or modifying database tables. We'll dive deeper into this concept and explore how migrations can help you maintain a consistent database schema.

Before we proceed, let's understand the idea of database migrations and why they are crucial for your Laravel application.

Database migrations are a way to manage database changes in a structured and organized manner. They allow you to define the structure of your database tables using PHP code. By creating migration files, you can version-control your database schema and apply changes consistently across different environments. This ensures that your database remains in sync with your application code and evolves alongside it.

Let's look at the migrations file we used in the previous lesson:

php
1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7class CreateTodosTable extends Migration 8{ 9 public function up() 10 { 11 Schema::create('todos', function (Blueprint $table) { 12 $table->id(); 13 $table->string('title'); 14 $table->text('description')->nullable(); 15 $table->timestamps(); 16 }); 17 } 18 19 public function down() 20 { 21 Schema::dropIfExists('todos'); 22 } 23}

Let's understand the key components of this migration file:

  • The CreateTodosTable class extends the Migration class provided by Laravel.
  • The up method is used to define the changes that should be applied to the database. In this case, we are creating a todos table with columns for title, description, and timestamps using the Schema::create method provided by Laravel.
    • The function takes two arguments: the table name and a closure that defines the table structure.
    • The Blueprint class is used to define the columns of the table.
    • The id method creates an auto-incrementing primary key column.
    • The string and text methods create columns of type VARCHAR and TEXT, respectively. The VARCHAR and TEXT are underlying SQL data types.
    • The timestamps method creates created_at and updated_at columns to track record creation and updates.
  • The down method is used to define the rollback operation that should be applied when the migration is rolled back. In this case, we are dropping the todos table using the Schema::dropIfExists method provided by Laravel.

After defining the migration file, you can run the migration using the php artisan migrate command. This command will execute the up method of the migration file and create the todos table in the database. You can also roll back the migration using the php artisan migrate:rollback command, which will execute the down method and drop the todos table.

You might notice that the migration class contains a timestamp, which serves as a unique identifier for the migration and is a common convention used in database migrations. This is crucial for the following reasons:

  • Uniqueness: It ensures that every migration has a unique name, even if two migrations are created with the same name but at different times.
  • Execution Order: The timestamp allows migration tools to execute the migrations in chronological order. This prevents schema conflicts by ensuring that changes are applied in the correct sequence.

Additionally, we can apply changes to existing tables. For instance, adding a completed column is done with a new migration:

php
1use Illuminate\Database\Migrations\Migration; 2use Illuminate\Database\Schema\Blueprint; 3use Illuminate\Support\Facades\Schema; 4 5class AddCompletedToTodosTable extends Migration 6{ 7 public function up() 8 { 9 Schema::table('todos', function (Blueprint $table) { 10 $table->boolean('completed')->default(false); 11 }); 12 } 13 14 public function down() { 15 Schema::table('todos', function (Blueprint $table) { 16 $table->dropColumn('completed'); 17 }); 18 } 19}

In this migration file, we are adding a completed column to the todos table. The up method uses the Schema::table method to modify an existing table. The boolean method creates a column of SQL type BOOLEAN, and the default method sets the default value of the column to false.

The down method defines the rollback operation, which drops the completed column from the todos table. Note, that the SQLite database does not support dropping columns, so you will see and empty down method in the practices.

Similarly, after doing any changes to the migration file, or creating a new one, you can run the migration using the php artisan migrate command to apply the changes to the database.

Migrations vs Direct Schema Modifications

While migrations are a powerful tool for managing database changes, there are scenarios where direct schema modifications might be more suitable. Let's explore when to use migrations and when direct schema modifications might be preferred.

When to Use Migrations

  • In projects where multiple developers are working on the same codebase, migrations ensure that everyone’s database is in sync.
  • If an application is deployed in multiple environments, migrations ensure that changes applied in one environment can be easily applied to others.
  • For projects where database schema evolution needs to be tracked or rolled back, migrations provide a detailed history of changes. In contrast, direct schema changes don’t have inherent version control, making it difficult to know when and why changes were made or to revert them if necessary.

When Direct Schema Modifications Might Be More Suitable

  • For simple applications or one-person projects where database changes are minimal and unlikely to be shared or deployed across multiple environments, direct modifications can be faster and simpler.
  • For minor, urgent changes in a live production database (e.g., adding an index to improve performance or fixing a critical column setting), a direct modification might be quicker than creating and testing a migration. However, these changes should be documented carefully.

Always remember that for significant schema changes, migrations can become complex, especially if they need to be reversed. Running migrations in production databases can sometimes be risky or slow, especially for large tables. Index changes, data type changes, or dropping columns on a large production table can take considerable time and impact performance.

Why It Matters

Understanding database migrations is essential for every developer working with Laravel. Migrations not only foster collaboration within a development team but also ensure that your application remains stable and consistent as it grows. By leveraging migrations, you are empowered to manage and track changes to your database schema efficiently. This is particularly important in large projects where multiple developers are contributing, and database structures evolve over time.

With these skills, you'll be better equipped to handle real-world applications and adapt them as requirements change. Ready to solidify your understanding of database migrations? Let's proceed to the practice section and apply your newfound knowledge in a hands-on environment!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.