Sign In
Sign In

Migrations and Seeders in Laravel: Database Setup

Migrations and Seeders in Laravel: Database Setup
Hostman Team
Technical writer
Laravel
16.10.2024
Reading time: 9 min

Migrations and seeders are two tools in the PHP framework Laravel that simplify working with databases and solve issues related to inconsistency. In Laravel, migrations function similarly to version control for databases. They allow the development team to define and share a common database schema, ensuring all team members are aware of any changes.

Seeders in Laravel are tools used to populate the database with test data. There are several seeder classes available that allow for control over the seeding process.

In this article, you will learn how to get started with Laravel and create migrations and seeders.

Installing and Setting Up Laravel

In this tutorial, we'll use Docker to run a Laravel application. Laravel provides a built-in command-line interface called Laravel Sail for Docker, which is in the Laravel package by default.

We will install all necessary software on Windows 10. This guide consolidates instructions from various sources, including Microsoft, Docker, and Laravel. First, we will install WSL (Windows Subsystem for Linux), then Docker, and finally Laravel. The instructions below are specifically for Windows 10. For other operating systems, refer to the official Laravel documentation.

Installing WSL

WSL (Windows Subsystem for Linux) is a compatibility layer for running Linux applications on Windows.

If you have Windows 10 version 2004 or later, you can install WSL by running this command in PowerShell as an administrator:

wsl --install

By default, the Ubuntu distribution will be used. We need WSL 2, so let's switch to this version. This process will take a few minutes:

wsl --set-version Ubuntu 2

To check the version, use the command:

wsl.exe -l -v

Example output:

PS C:\WINDOWS\system32> wsl.exe -l -v
 NAME      STATE           VERSION
* Ubuntu    Stopped         2

To check your Windows version, press Win+R, and type winver. A window will appear with your system information.

If your version is lower than 2004, the wsl --install command will not work. Here's a list of steps for older versions (you'll need at least version 1903 with build 18362):

  1. Enable the Windows Subsystem for Linux: Open PowerShell as an administrator and run:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
  1. Enable the Virtual Machine feature: Run this command in the same PowerShell window:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  1. Restart your computer to complete the installation.

  2. Download and install the Linux kernel update package from this link.

  3. Set WSL 2 as the default version: After rebooting, open PowerShell again as an administrator and run:

wsl --set-default-version 2
  1. Install a Linux distribution: Choose your preferred Linux distribution, download it from the Microsoft Store, and install it. After installation, you can access your Linux terminal from the search menu.

Installing Docker

Go to docker.com, click Get Started, and download Docker Desktop for Windows. During the installation process, make sure to select the option Use WSL 2 instead of HYPER-V.

Open Docker, click the gear icon on the top panel to enter the settings menu.

Image1

In the General tab, you can adjust the basic settings. Here, you can enable WSL 2 and disable unnecessary features like telemetry. After setting these options, move to the Resources tab and enable integration with Ubuntu.

Image4

After this, click Apply & Restart. Docker will reboot with the new settings.

Setting up Laravel

Let's create a new Laravel application. Open the Ubuntu terminal and run the following command:

curl -s https://laravel.build/example-app | bash

Here, example-app is the directory for the new Laravel application. On the first run, the command will download the necessary images, which may take some time.

Image3

Once the download completes, Laravel Sail will be available. Navigate to the project directory:

cd example-app

Next, create Laravel Sail containers:

./vendor/bin/sail up

The container creation process may take a while, but subsequent Sail launches will be faster. Sail will start the Laravel web application with informational resources that are accessible on localhost.

If you encounter the error:

The Stream Or File “/Var/Www/Html/Storage/Logs/Laravel.Log” Could Not Be Opened In Append Mode: Failed To Open Stream: Permission Denied

You need to change the file permissions for docker.sock using this command:

sudo chmod 666 /var/run/docker.sock

Working with Migrations

As mentioned earlier, migrations are similar to version control. They allow users to create and modify the database schema or roll back changes. Migrations do not define the content of tables (except for constraints).

In a Laravel project, migration files are stored in the directory at ./database/migrations/. When you create a Laravel Sail application, it comes with several migrations by default.

Image2

Let's run these migrations and check the results. Open the Ubuntu terminal and enter the following commands:

./vendor/bin/sail up -d     // Start the application in the background
./vendor/bin/sail artisan migrate

Output:

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (1,846.42ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (1,965.53ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (2,196.68ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (3,325.95ms)

Migrations in Laravel are executed in the order they are created. This allows Laravel to implement the rollback mechanism correctly. Running migrations in an ad hoc manner can lead to data loss in the database.

Next, let's check whether the corresponding tables were created in the database. We can connect to the database using HeidiSQL. The connection parameters can be found in the environment configuration file .env:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=example_app
DB_USERNAME=sail
DB_PASSWORD=password

You can also set different parameters here.

Once connected to the database, you will see its current state.

Now, let's create a new migration and see how it works.

Creating Migrations

First, let's create a migration class. To do this, execute the make:migration command in the Ubuntu terminal:

./vendor/bin/sail artisan make:migration example_migr

Output:

Created Migration: 2024_06_02_005033_example_migr

The name of the migration consists of two parts: a timestamp and a name chosen by the user. The timestamp helps to run migrations in the correct order.

Now, open the created file in any editor of your choice:

<?php

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

return new class extends Migration
{
    /**
     * Run the migration
     *
     * @return void
     */
    public function up()
    {
        //
    }

    /**
     * Rollback the migration
     *
     * @return void
     */
    public function down()
    {
        //
    }
};

Migrations use two methods: up() and down(). In the up() method, you describe the database changes that need to be executed when the migration is run. The down() method undoes the changes made by up().

Now let's write the migration code to create a table called items with the following columns:

  • id — primary key

  • name — name of the item

  • cost — price of the item

  • count — quantity of the item in stock

Here is the migration code for this table:

<?php

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

return new class extends Migration
{
    /**
     * Run the migration.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->integer('count');
            $table->integer('cost');
        });
    }

    /**
     * Rollback the migration
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('items');
    }
};
  • Schema::create creates a new table.

  • Schema::dropIfExists deletes the table if it exists.

Save the changes to the file and run the migration again through the terminal:

./vendor/bin/sail artisan migrate

Output:

Migrating: 2024_06_02_005033_example_migr
Migrated:  2024_06_02_005033_example_migr (658.56ms)

Rolling Back Migrations

There are several commands to rollback migrations:

  • migrate:rollback — rolls back the last migrate command. You can also rollback a specific number of migrations using the --steps [number] parameter.

  • migrate:reset — rolls back all migrations.

  • migrate:refresh — rolls back all migrations and then runs migrate.

  • migrate:fresh — deletes all tables from the database and then runs migrate.

Seeders

At this point, the database only contains empty tables. They can be filled using seeders. Seeders are necessary for populating the database with dummy or test data.

You can create a seeder using the make:seeder command:

./vendor/bin/sail artisan make:seeder ExampleSeeder

Output:

Seeder created successfully.

All seeders are located in the database/seeders directory. Navigate to it and open ExampleSeeder in your editor:

<?php

namespace Database\Seeders;

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

class ExampleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

In the run() method, you need to place the code for generating data. Let's add 10 random records to the items table:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;

class ExampleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for ($i = 1; $i <= 10; $i++) {
            DB::table('items')->insert([
                'id' => $i,
                'name' => Str::random(5),
                'cost' => rand(5, 20),
                'count' => rand(0, 10),
            ]);
        }
    }
}

Using the insert() command, we add a record to the items table. However, new seeder classes do not run automatically. You need to add its call to the main DatabaseSeeder class:

public function run()
{
   $this->call(ExampleSeeder::class);
}

After that, we can run the data seeding:

./vendor/bin/sail artisan db:seed

Output:

Seeding: Database\Seeders\ExampleSeeder
Seeded: Database\Seeders\ExampleSeeder (841.68ms)
Database seeding completed successfully.

And here is the result in the database:

B239b3b8 C6df 4d73 Bdcd 6e238b6ae5b8

Conclusion

We have explored tools in the Laravel framework, such as migrations and seeders, which simplify working with databases. You can always rent a server for any experiments on Hostman.

Laravel
16.10.2024
Reading time: 9 min

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start
Email us