Laravel Logo

Now that we have discussed creating factories, we can look at how to use these factories to seed our database with test data.

Why Do They Exist and When Should You Use It?

Seeders allow you to generate a lot of test data very quickly. Instead of manually creating a large amount of test data you can leverage your factories to quickly spin up tens, hundreds, or even thousands of test rows so you can test and demo your application.

Let’s Build a Seeder

In this section we’re going to build a seeder using the ProjectFactory we created in our last post. To do this we’re going to use artisan’s make:seeder command.

$ php artisan make:seeder ProjectTableSeeder
Seeder created successfully.

This will create a class in the file “database/seeds/ProjectTableSeeder.php” that looks like the following.

<?php

use Illuminate\Database\Seeder;

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

We’re not going to put anything into this just yet because there’s still some setup we need to do. First, open “database/seeds/DatabaseSeeder.php”. It will look like the following.

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
    }
}

We’re going to change it so it knows about our ProjectTableSeeder class.

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

This will tell Laravel to look for the ProjectTableSeeder class when we want to seed our database. This is done by using the db:seed command. If we run this command now we’ll receive the following error message.

Illuminate\Contracts\Container\BindingResolutionException : Target class [ProjectsTableSeeder] does not exist.

In order to fix this we need to run composer dump-autoload so it can detect the new class. After composer runs we can run db:seed again and get the following results.

ubuntu@ubuntu-xenial:/var/www$ php artisan db:seed
Seeding: ProjectsTableSeeder
Seeded:  ProjectsTableSeeder (0 seconds)
Database seeding completed successfully.

Because we didn’t actually put anything in our seeder this didn’t do anything so let’s revisit our ProjectTableSeeder and update it to create 100 Projects for us.

public function run()
{
    factory(Project::class, 100)->create();
}

Now we can run db:seed and the command will create the Projects.

ubuntu@ubuntu-xenial:/var/www$ php artisan db:seed
Seeding: ProjectsTableSeeder
Seeded:  ProjectsTableSeeder (0.41 seconds)
Database seeding completed successfully.

See how it took 0.41 seconds instead of 0. That’s artisan creating 100 Projects.

We can also create a TasksTableSeeder and add it to DatabaseSeeder. We could continue to add $this->call() to the DatabaseSeeder’s run() function but we can also change the call to the call() function to be an array of all the classes we need.

$this->call([
    TasksTableSeeder::class,
    ProjectsTableSeeder::class,
]);

Now db:seed will also create the Tasks for us.

ubuntu@ubuntu-xenial:/var/www$ php artisan db:seed
Seeding: TasksTableSeeder
Seeded:  TasksTableSeeder (0.64 seconds)
Seeding: ProjectsTableSeeder
Seeded:  ProjectsTableSeeder (0.15 seconds)
Database seeding completed successfully.

Seeding a Single Table

In cases where we need to create a bunch of data for a specific module for testing/demo purposes, db:seed has a --class parameter that will allow you to run a single seeder.

ubuntu@ubuntu-xenial:/var/www$ php artisan db:seed --class=TasksTableSeeder
Database seeding completed successfully.

Refresh and Seed

If you ever hit a point where you need to reset your database but also have test data, migrate:refresh also has a --seed parameter so you can refresh you database and seed it with new data at the same time.

ubuntu@ubuntu-xenial:/var/www$ php artisan migrate:refresh --seed
Rolling back: 2020_01_10_014509_create_projects_table
Rolled back:  2020_01_10_014509_create_projects_table (0 seconds)
Rolling back: 2019_10_11_011555_create_tasks_table
Rolled back:  2019_10_11_011555_create_tasks_table (0 seconds)
Rolling back: 2019_08_19_000000_create_failed_jobs_table
Rolled back:  2019_08_19_000000_create_failed_jobs_table (0 seconds)
Rolling back: 2014_10_12_100000_create_password_resets_table
Rolled back:  2014_10_12_100000_create_password_resets_table (0 seconds)
Rolling back: 2014_10_12_000000_create_users_table
Rolled back:  2014_10_12_000000_create_users_table (0 seconds)
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.02 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.03 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.01 seconds)
Migrating: 2019_10_11_011555_create_tasks_table
Migrated:  2019_10_11_011555_create_tasks_table (0.03 seconds)
Migrating: 2020_01_10_014509_create_projects_table
Migrated:  2020_01_10_014509_create_projects_table (0.01 seconds)
Seeding: TasksTableSeeder
Seeded:  TasksTableSeeder (0.87 seconds)
Seeding: ProjectsTableSeeder
Seeded:  ProjectsTableSeeder (0.22 seconds)
Database seeding completed successfully.

Hopefully this has been as helpful to you as it has to me. Check back soon for more artisan commands.