Learn Laravel Migrations [In-Depth Tutorial]


Laravel

Author: Steve Alila
Reviewer: Deepak Prasad

In Laravel Migration, we’ll help you navigate through a myriad of things. We’ll help you with the setup, creating and running migrations, managing columns and tables. Plus we’re going to throw in some advanced features like seeding data, best practices for maintaining your database schema efficiently.

Think of Laravel Migration as a version control feature for database schemas. It allows devs to modify and share an app’s database schema in a team environment easily. Instead of manually writing SQL queries, Migrations let you define relationships between tables and their data. This approach simplifies the process of creating and modifying tables. Which makes it essential for developing robust Laravel projects.

The consistency provided by Migrations across different development environments is what gives applications smooth deployments and updates. By using this feature, developers can handle their database schema evolution properly — reducing the risk of conflicts during operation. It also curbs the chances of committing errors when interacting with databases.

 

1. Getting started with Laravel Migration

1.1 Setting Up Laravel Project

Before setting up migrations, ensure Laravel is installed. We will create a separate project to demonstrate the use cases of Laravel Migration. In my system I keep all my projects under /opt/projects but you can choose your own path.

Open your terminal or command prompt and run the following Composer command to create a new Laravel project named "LaravelMigrationGuide":

sudo mkdir -p /opt/projects
sudo chmod 777 /opt/projects
cd /opt/projects
composer create-project --prefer-dist laravel/laravel LaravelMigrationGuide

This command will download and install a fresh Laravel application in a directory named "LaravelMigrationGuide". Once the installation is complete, you can navigate into your project directory with:

cd LaravelMigrationGuide

You'll need to configure your database settings in the .env file at the root of your Laravel project. We have also covered this while we were installing Laravel, so I will just use the same values:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_laravel_db
DB_USERNAME=user1
DB_PASSWORD=Passw0rd

 

1.2 Generate a Migration File

Use Laravel's Artisan command-line tool to create a migration. Migrations are PHP files that contain a class with methods to make changes to the database. For example, to create a migration for a "posts" table, you would run:

php artisan make:migration create_posts_table --create=posts
Learn Laravel Migrations [In-Depth Tutorial]

This command creates a new migration file in the database/migrations directory. The file is named with the current date and time, ensuring the migrations are run in the order they were created.

 

1.3 Writing the Migration

Open the newly created migration file i.e. database/migrations/2024_02_17_090841_create_posts_table.php in your favorite text editor or IDE. You'll see two methods: up and down. The up method is used to add new tables, columns, or indexes to the database, while the down method should reverse whatever operations the up method performs.

Here's an example of what the up method might look like for a simple "posts" table:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('body');
        $table->timestamps();
    });
}

And the corresponding down method:

public function down()
{
    Schema::dropIfExists('posts');
}

 

1.4 Run the Migration

Once your migration file is set up, apply the changes to your database by running:

php artisan migrate

This command runs all of your application's pending migrations, in this case, creating the "posts" table in your database.

Learn Laravel Migrations [In-Depth Tutorial]

 

2. Performing Different Migration Operations

In this section we will be covering adding and removing tables and columns, as well as modifying column attributes and data types.

 

2.1 Adding a New Table

Suppose you want to add a new table called comments to store user comments on posts. First, generate a migration file:

php artisan make:migration create_comments_table --create=comments
Learn Laravel Migrations [In-Depth Tutorial]

Open the generated migration file in database/migrations and modify the up method to define your table:

Schema::create('comments', function (Blueprint $table) {
    $table->id();
    $table->text('content');
    $table->unsignedBigInteger('post_id');
    $table->foreign('post_id')->references('id')->on('posts');
    $table->timestamps();
});

Apply the migration to create the table in your database:

php artisan migrate

 

2.2 Adding a Column to an Existing Table

Now, let's say you want to add an email column to the comments table:

Create a migration for modifying the table:

php artisan make:migration add_email_to_comments_table --table=comments
Learn Laravel Migrations [In-Depth Tutorial]

In the migration file database/migrations/2024_02_17_092438_add_email_to_comments_table.php, specify the column to add:

Schema::table('comments', function (Blueprint $table) {
    $table->string('email')->nullable();
});

Execute the migration to add the column:

php artisan migrate

 

2.3 Removing a Column

If you decide that the email column is unnecessary and want to remove it:

Create a migration for dropping the column:

php artisan make:migration remove_email_from_comments_table --table=comments
Learn Laravel Migrations [In-Depth Tutorial]

Specify the column to remove in the newly created migration file i.e. database/migrations/2024_02_17_092642_remove_email_from_comments_table.php:

Schema::table('comments', function (Blueprint $table) {
    $table->dropColumn('email');
});

Apply the migration to remove the column:

php artisan migrate
Learn Laravel Migrations [In-Depth Tutorial]

 

2.4 Modifying Column Attributes

Lastly, suppose you need to change the content column in the comments table to a VARCHAR type instead of TEXT:

Start by creating a migration for the modification:

php artisan make:migration change_content_type_in_comments_table --table=comments
Learn Laravel Migrations [In-Depth Tutorial]

In the migration file, use the change method to modify the column type. Note that you may need to require the Doctrine DBAL package to change column types:

composer require doctrine/dbal

Then, update the migration file database/migrations/2024_02_17_092928_change_content_type_in_comments_table.php:

Schema::table('comments', function (Blueprint $table) {
    $table->string('content', 255)->change();
});

Execute the migration to apply the change:

php artisan migrate
Learn Laravel Migrations [In-Depth Tutorial]

 

3. Rolling Back Migrations

The process of rolling back migrations in Laravel makes it possible for you to reverse a singular or multiple migration operations. There are moments when errors occur during the test phase of your new database schemas, and making corrections becomes vital. Good thing that Laravel offers various Artisan commands to effectively manage such rollback tasks as this.

 

3.1 Rolling Back the Last Migration Operation

The simplest form of rollback is to undo the last batch of migrations that were executed. You can accomplish this by running:

php artisan migrate:rollback

This command is used to focus on the previous "batch" of migrations that were run. Laravel takes migrations it runs together, and groups them into one single batch. Whenever you execute a rollback command, all migrations in the recent batch are reversed from when they were applied.

 

3.2 Rolling Back Multiple Migrations

If you want to roll back more than just the last batch of migrations, you can specify how many steps (batches) you want to go back using the --step option. For example, to roll back the last two batches of migrations, you would run:

php artisan migrate:rollback --step=2

This command sequentially undoes the migrations in reverse order, batch by batch, according to the number specified in the --step option.

 

3.3 Resetting the Database

When you need to roll back all migrations (i.e., completely reset your database schema), Laravel provides a command for that as well:

php artisan migrate:reset

Running this command will start rolling back all of your migrations done batch by batch. It will keep going until the database is in the original state it was before any of them were run. This can be extremely beneficial when you want to wipe out your database schema and start fresh while you’re in development.

 

3.4 Refreshing Migrations

Another useful command is migrate:refresh, which rolls back all of your application's migrations and then re-runs them all from the beginning. This is especially handy when you want to rebuild your entire database:

php artisan migrate:refresh

Optionally, you can combine the refresh operation with the --seed option to reseed your database after refreshing the migrations:

php artisan migrate:refresh --seed

This is very useful for resetting your database to a known state with pre-populated data during development.

 

3.5 Fresh Migrations

Lastly, Laravel offers the migrate:fresh command. This command drops all tables from the database and then executes the migration commands:

php artisan migrate:fresh

Like with migrate:refresh, you can also use the --seed option with migrate:fresh to seed your database after it has been cleared and the migrations have been re-applied.

php artisan migrate:fresh --seed

 

3.6 Verify Migration Status

The migrate:status command provides a straightforward way to see the migration status in your Laravel application. It lists all migrations along with their status (whether they've been run or not):

php artisan migrate:status

For Example, here 2024_02_17_090841_create_posts_table status in Run as we triggered migration earlier.

Learn Laravel Migrations [In-Depth Tutorial]

Now let's rollback last migration:

Learn Laravel Migrations [In-Depth Tutorial]

Verify the migration status again:

Learn Laravel Migrations [In-Depth Tutorial]

After you rolled back the database migration, you ran php artisan migrate:status and saw create_posts_table listed as "Pending". This indicates that the migration is no longer applied to the database. It confirms successfully rolled back. The ‘pending’ status means that this migration has been canceled and waiting to be rerun again in the future if necessary.

The other migrations (create_users_table, create_password_reset_tokens_table, create_failed_jobs_table, and create_personal_access_tokens_table) still show as "[1] Ran" because they were part of the initial batch of migrations and were not affected by the rollback. Migrations from your most recent batch (in this case, only a single one: create_posts_table) was what got rolled back.

 

4. Advanced Migration Features in Laravel

Laravel is really good at managing your database migrations. It’s great for even larger applications too! There are a few features that make it particularly awesome. Two of those features are called migration squashing and schema dumping.

 

4.1 Migration Squashing and Schema Dumping

As your Laravel application expands, the number of migrations does as well. As this happens, your migration commands and version control operations may become slower. To counteract this slow down, you can take advantage of Laravel’s optimization features: migration squashing and schema dumping.

Migration Squashing works by condensing all of your separate migration files into one SQL file. In simpler terms, it takes the data stored in each individual file and compiles it to create a comprehensive profile of your database schema based on your migrations.

To squash migrations, you can use the schema:dump command:

php artisan schema:dump

This command creates a schema file in database/schema directory. When you run migrations (php artisan migrate), Laravel will first check for the schema file and apply it, followed by any migrations that were not part of the schema dump. This significantly speeds up migration execution, especially in fresh installations or CI/CD pipelines.

Schema Dumping: The schema:dump command also supports a --prune option, which not only dumps the schema but also deletes all existing migration files that are already represented in the schema dump. This helps in keeping the migrations folder clean and manageable.

php artisan schema:dump --prune

 

4.2 Managing Indexes, Primary, Unique, and Foreign Keys

Laravel's migration system provides an expressive syntax for defining indexes and keys on your tables, which are crucial for database performance and integrity.

Primary Keys: By default, the id() method in a migration creates an auto-incrementing primary key column:

$table->id();

Unique Keys: To ensure that each value in a column is unique, you can use the unique() method:

$table->string('email')->unique();

Foreign Keys: Laravel makes defining foreign key constraints straightforward. First, define the column, then chain the foreign() method with references() and on() to specify the foreign key relationship:

$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');

Laravel also supports cascading on delete or update actions using onDelete() and onUpdate() methods.

Indexes: Besides primary and unique keys, you might want to index other columns for faster query performance. You can do so by using the index() method:

$table->string('name')->index();

Laravel supports various types of indexes, including simple, composite, and full-text indexes, allowing you to optimize query performance based on your specific use cases.

 

5. Summary

Mastering migrations in Laravel is a must if you want to make managing your database schema changes easier. It’ll help you collaborate across any development environment smoothly. With it, you can automate schema updates, which makes both deployment and testing faster. The expressive syntax of its schema definitions also improves how readable and manageable your projects are. When you get more comfortable with the tool, there’s advanced features like migration squashing and schema dumping that’ll help optimize performance even more. Plus, there's support for indexes and keys built right into it too. That helps avoid performance problems and keep your database intact when working on big applications. Developers who’ve worked with Laravel already know this – understanding migrations is one of the first things to do when picking up the framework. So start learning now if you’re serious about building feature-rich systems that scale as they grow.

You can further read Laravel Migrations for more information.

 

Steve Alila

Steve Alila

He specializes in web design, WordPress development, and data analysis, with proficiency in Python, JavaScript, and data extraction tools. Additionally, he excels in web API development, AI integration, and data presentation using Matplotlib and Plotly. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment