Laravel Migrations Tutorial with example | All about Migrations Guide in laravel

By Ved Prakash N | Nov 26, 2023 | Laravel
Share : Whatsapp

https://www.fundaofwebit.com/post/laravel-migrations-tutorial-with-example

Laravel Migrations Tutorial with example | All about Migrations in Laravel 10


Laravel Migrations is a powerful tool that helps manage and control database schema changes in a structured and consistent manner, making database development and maintenance more manageable and organized. Laravel Migrations are a version control system for your database schema.


In this post, you will learn how to use migrations in Laravel and what all things can be done with Laravel migration artisan command, so let's get started:


1. Create a Migration

In Laravel, you can create a migration using the make:migration Artisan command. Open your terminal and navigate to your Laravel project directory. Then, run the following command:

Step 1: Create migration:

php artisan make:migration create_products_table

This command will create a new migration file in the database/migrations directory with a name like 2023_11_27_032932_create_products_table.php. The timestamp in the filename ensures that migrations are executed in the order they were created.

Note: In a migration artisan command: create_{your_table_name}_table. "create" and "table" word are fixed prefixes, so you are creating a new table with those words.


Step 2: Define the Schema in the Migration File

Let's open the new migration file from the database/migrations directory named as 2023_11_27_032932_create_products_table and add the columns to the migration file.  

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();

            $table->string('name');
            $table->text('description')->nullable();
            $table->decimal('price', 8, 2);
            $table->integer('stock');
           
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

In this example, the migration creates a products table with columns for id, name, description, price, stock, and timestamps (created_at and updated_at).


Step 3: Run the Migration

Let's migrate the database migration file into the database using Artisan command. so it will create a table in the database.

php artisan make:migrate


2. Adding New Columns in existing Table 

STEP 1: Run the following command to create a new migration file that adds a new_column as "status" to the above products table:

Syntax for the migration artisan command: php artisan make:migration add_NEW_COLUMN_to_MY_TABLE_NAME_table --table=MY_TABLE_NAME

php artisan make:migration add_status_to_example_table --table=products


STEP 2: let's add the new column as given below. 

Open the newly created migration file (e.g., 2023_09_18_123456_add_status_to_products_table.php) and modify the up and down methods as follows:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('products', function (Blueprint $table) {

            $table->boolean('status')->default(1)->comment('1=active,0=in-active');

        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('products', function (Blueprint $table) {

            $table->dropColumn('status');

        });
    }
};


Step 3: Run the Migration

So this below command will executes all pending migrations and also it will add new columns named status to your existing database table products.

php artisan make:migrate

This command executes all pending migrations. Laravel keeps track of which migrations have already been run in the migrations table of your database.


3. Add Columns after a specific column

Example 1:

public function up(): void
{
    Schema::table('products', function (Blueprint $table) {

        $table->after('description', function ($table) {
            $table->decimal('original_price', 8, 2);
            $table->string('small_description', 500);
        });

    });
}


Example 2: 

public function up(): void
{
    Schema::table('products', function (Blueprint $table) {

        $table->decimal('original_price', 8, 2)->after('price')->nullable();
        $table->string('small_description')->after('name')->nullable();

    });
}


4. Adding Column To Index

1. You can do it at table creation and add Index to the column:

public function up(): void
{
    Schema::table('products', function (Blueprint $table) {

        $table->string('product_code')->unique()->index();

    });
}

2. You can alter the existing table and just create a new index using:

public function up(): void
{
    Schema::table('products', function (Blueprint $table) {

        $table->index('product_code');

    });
}

3. If you want to RENAME the index:

$table->renameIndex('product_code', 'your_new_column');

4. If you want to REMOVE the index:

$table->dropIndex('product_code');


5. Foreign Key Relation

Take an example for the products table, where we are storing the category ID in it. Let's give the foreign key relation as follows.  

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();

        $table->unsignedBigInteger('category_id');

        // ... your existings columns
        // ... your existings columns

        $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');

        $table->timestamps();
    });
}

In the products table migration, notice the column category_id that's set as an unsigned big integer to hold the foreign key reference to the id column in the categories table. The foreign() method then establishes the foreign key relationship, referencing the id column in the categories table.


You have many ways to give a Foreign key in Laravel

1. Referencing the column and giving the relation.

public function up(): void
{
    Schema::table('products', function (Blueprint $table) {

        $table->unsignedBigInteger('category_id');
        $table->foreign('category_id')->references('id')->on('categories');
    });
}

2. This Foreign key relation is shorter. It will automatically take the id and reference and all. 

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();

        $table->foreignId('category_id')->constrained('categories')->onUpdate('cascade')->onDelete('cascade');

        // ... your existings columns
        // ... your existings columns

        $table->timestamps();
    });
}

Any additional column modifiers must be called before constrained().

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();

        $table->foreignId('category_id')
                    ->nullable()
                    ->constrained('categories')
                    ->onUpdate('cascade')->onDelete('cascade');

        // ... your existings columns
        // ... your existings columns

        $table->timestamps();
    });
}

3. Foreign Key relation with Index

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();

        $table->foreignId('category_id')->index();

        // ... your existings columns
        // ... your existings columns

        $table->timestamps();
    });
}


6. Migration Commands

1. Run Migration: Executes all pending migrations that haven't been run yet.

php artisan migrate

2. Rolling Back the Last Migration:

php artisan migrate:rollback

3. Rolling Back Migrations Batch Number wise:

php artisan migrate:rollback --step=1

4. Resetting migrations:

You can use the migrate:reset command to roll back all your application migrations in the database.

php artisan migrate:reset

5. Refreshing migrations

You can use the migrate:refresh command to recreate your entire database. It rolls back all your migrations and executes the migrate command again.

php artisan migrate:refresh

6. Fresh migration

The migrate:fresh command drops all the tables in the database before executing the migrate command.

php artisan migrate:fresh

Extra caution should be taken with migrate:fresh on applications that share databases because it drops all the tables in that database.

7. Rolling Back and Re-migrating with Seed Data:

php artisan migrate:refresh --seed


7. Seeders in Laravel

In Laravel, seeders are used to populate the database with sample or default data. Here are the primary commands related to seeding in Laravel:

Creating a Seeder using Artisan Command: (Syntax)

php artisan make:seeder SeederName

This command generates a new seeder class in the database/seeders directory.

1. Create a ProductSeeder - Let's see with an example:

STEP 1: Generate the Seeder: 

php artisan make:seeder ProductSeeder

This command generates a new seeder class in the database/seeders directory named ProductSeeder.php file.

STEP 2: Modify the ProductSeeder class (ProductSeeder.php) in database/seeders:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use App\Models\Product;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $products = [
            [
                'name' => 'Product 1',
                'description' => 'Description for Product 1',
                'price' => 29.99,
                'stock' => 100,
                'created_at' => now(),
                'updated_at' => now(),
            ],
            [
                'name' => 'Product 2',
                'description' => 'Description for Product 2',
                'price' => 39.99,
                'stock' => 50,
                'created_at' => now(),
                'updated_at' => now(),
            ],
        ];

        DB::table('products')->insert($products);

        //OR

        Product::createMany($products);
    }
}

If you are using the Product Model to insert data. So Ensure the Product model has the protected $fillable property set with the columns you want to mass-assign, typically including all the columns except the primary key (id).

STEP 3: Run the Seeder

php artisan db:seed --class=ProductSeeder


2. Running All Seeders:

STEP 1: You can give all the Seeders in DatabaseSeeder.php file ( database/ seeders/ DatabaseSeeder.php ) as follows:

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call(CategorySeeder::class);
        $this->call(ProductSeeder::class);
        // Add more seeders as needed
    }
}


STEP 2: Run the following command to execute all seeders:

php artisan db:seed

Executes all seed classes within the DatabaseSeeder class (database/ seeders/ DatabaseSeeder.php).


3. Refreshing and Seeding Database
Refreshing Database and Running Seeders:
php artisan migrate:refresh --seed
Rolls back all migrations, re-runs them, and seeds the database.

4. Truncating Tables before Seeding :

php artisan db:seed --class=SeederName --truncate
Truncates tables before seeding data.


I hope this helps you in your future coding. Thanks for reading.