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.
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.
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):
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
Enable the Virtual Machine feature: Run this command in the same PowerShell window:
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
Restart your computer to complete the installation.
Download and install the Linux kernel update package from this link.
Set WSL 2 as the default version: After rebooting, open PowerShell again as an administrator and run:
wsl --set-default-version 2
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.
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.
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.
After this, click Apply & Restart. Docker will reboot with the new settings.
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.
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
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.
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.
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)
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
.
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:
We have explored tools in the Laravel framework, such as migrations and seeders, which simplify working with databases. You can always rent a virtual server for any experiments on Hostman.