Laravel — P33: Seeders

Laravel Seeders: Planting the Seeds of Your Database

The seeder is the last piece of the Factory/Faker/Seeder puzzle. We’ve covered the Factory and used Faker with it. Now it’s time to automate this whole process and use seeders.

The seeder will populate your database tables when you run the following command:

php artisan db:seed

That one command can call one or more seeders.

You can also call an individual seeder:

php artisan db:seed --class=UserSeeder

Let’s create a seeder and see how this all ties in. Run the following command to create a User Seeder:

# php artisan make:seeder UserSeeder

   INFO  Seeder [database/seeders/UserSeeder.php] created successfully.  Artisan will generate a new class called UserSeeder under database/seeders/UserSeeder.php.
Artisan will generate a new class called UserSeeder under database/seeders/UserSeeder.php.
<?php

namespace Database\Seeders;

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

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

It’s just a class with an empty run() method. The run() method is where we’ll add all of our code to see the database. Let’s first populate the users table without using factories.

<?php

namespace Database\Seeders;

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

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => Str::random(10),
            'email' => Str::random(10).'@gmail.com',
            'password' => Hash::make('password'),
        ]);
    }
}

As you can probably guess, this will insert a new record into the users table. Let’s call the seeder and verify that the data persists:

# php artisan db:seed --class=UserSeeder

   INFO  Seeding database.  

Checking the users table, I can verify that the new record is there.

56 | arM9uxZyEh | hZ5kz4vNwh@gmail.com | NULL | $2y$10$u2S8uzEVfGIRt89H55oWVug4wcK7BjDm.TsZ7juuhSCn6dz2fPdHS | NULL | NULL | NULL
We’re starting to add code into multiple places again. As you can see, the run() method just runs whatever’s inside of it when the db:seed command is issued. So why can’t it just run our factory command? Well it can, and it will, as many times as we want it to.
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use App\Models\User;
use Illuminate\Database\Seeder;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        User::factory()->count(10)->create();
    }
}

The code above will store 10 new random entries (thanks to faker) inside of our database. Let’s run the same command again and verify that they’re there.

# php artisan db:seed --class=UserSeeder

   INFO  Seeding database.
mysql> select * from users;
+----+---------------------------+-------------------------------+---------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name                      | email                         | email_verified_at   | password                                                     | remember_token | created_at          | updated_at          |
+----+---------------------------+-------------------------------+---------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
|  1 | Kristy Hettinger          | ismith@example.com            | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | ukozgCinvw     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  2 | Zackary Goldner           | dooley.emery@example.net      | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | VvmKmT6FZs     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  3 | Mr. Quentin VonRueden DVM | green.gabriella@example.net   | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | OIriBYpC98     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  4 | Westley Schmitt           | abbott.gerardo@example.com    | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | vNKd0IPE7l     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  5 | Stefanie Shanahan         | kavon.thiel@example.com       | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | hmz7wazZyX     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  6 | Alessandra Predovic       | schowalter.morris@example.org | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | bQsqDwPP9V     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  7 | Elton Olson IV            | vance77@example.net           | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | loPaofpFGF     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  8 | Vincenzo Prohaska         | purdy.gaetano@example.com     | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | v5PiCo0X6R     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
|  9 | Kellen Olson              | fgrimes@example.com           | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | yKaHFB8nC5     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
| 10 | Mylene Wisoky             | rebeka34@example.com          | 2023-01-17 16:11:51 | $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi | S0G4dAwmt4     | 2023-01-17 16:11:51 | 2023-01-17 16:11:51 |
+----+---------------------------+-------------------------------+---------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
10 rows in set (0.00 sec)
Let’s create another seeder for our Car model and utilize the CarFactory that we created earlier.
# php artisan make:seeder CarSeeder

   INFO  Seeder [database/seeders/CarSeeder.php] created successfully.

<?php

namespace Database\Seeders;

use App\Models\Car;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class CarSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Car::factory()->count(50)->create();
    }
}
We can run the db:seed command to populate the cars table with 50 new entries.
php artisan db:seed --class=CarSeeder
Verify that the cars table contains 50 new rows.
mysql> select * from cars;
+----+---------------+-------------+---------------------+---------------------+
| id | make          | model       | created_at          | updated_at          |
+----+---------------+-------------+---------------------+---------------------+
|  1 | reprehenderit | voluptas    | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  2 | aliquam       | aut         | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  3 | et            | molestiae   | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  4 | et            | est         | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  5 | quidem        | ad          | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  6 | enim          | quod        | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
|  7 | et            | fugiat      | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
...
| 49 | incidunt      | dolore      | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
| 50 | natus         | soluta      | 2023-01-17 16:24:07 | 2023-01-17 16:24:07 |
+----+---------------+-------------+---------------------+---------------------+
50 rows in set (0.00 sec)

mysql> 

At this point, you can probably see the value of running multiple seeders with one command. If you had 50 seeders, you wouldn’t want to run 50 different commands. Luckily, Laravel addresses that issue as well.

DatabaseSeeder

You’ve probably noticed another class that was automatically created by Laravel called DatabaseSeeder (database/seeders/DatabaseSeeder.php).

<?php

namespace Database\Seeders;

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

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();
    }
}

You could uncomment the code and call the User factory directly from here, or you could use the call() method to call each of the seeders. According to Laravel’s documentation, “using the call method allows you to break up your database seeding into multiple files so that no single seeder class becomes overwhelmingly large.”

Let’s pass our UserSeeder and CarSeeder to the call() method. The call() method accepts an array as an argument where each element is the seeder class that you want to call.

<?php

namespace Database\Seeders;

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

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

We can now use the following command to call the DatabaseSeeder which will in turn call each of our specified seeders:

# php artisan db:seed

   INFO  Seeding database.  

  Database\Seeders\UserSeeder ............................................................ RUNNING  
  Database\Seeders\UserSeeder ..................................................... 125.58 ms DONE  

  Database\Seeders\CarSeeder ............................................................. RUNNING  
  Database\Seeders\CarSeeder ...................................................... 117.45 ms DONE  

# 

Artisan will provide us with messages letting us know that everything went well. You can also verify that the database tables have been seeded visually.

Running Seeders During Migration

When you run your migrate command, you can use the --seed flag to run your seeders. If you have too much data in your database tables already, you can always clear them out before running the seeder (migrate:fresh). You may want to do this each time anyway:

# php artisan migrate:fresh --seed

  Dropping all tables .................................................................. 74ms DONE

   INFO  Preparing database.  

  Creating migration table ............................................................. 19ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ................................................. 29ms DONE
  2014_10_12_100000_create_password_resets_table ....................................... 26ms DONE
  2019_08_19_000000_create_failed_jobs_table ........................................... 26ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ................................ 38ms DONE
  2023_01_12_185409_create_tests_table ................................................. 28ms DONE
  2023_01_12_194511_add_phone_to_tests_table ........................................... 15ms DONE
  2023_01_16_162646_create_cars_table .................................................. 16ms DONE

   INFO  Seeding database.  

  Database\Seeders\UserSeeder ............................................................ RUNNING  
  Database\Seeders\UserSeeder ..................................................... 108.18 ms DONE  

  Database\Seeders\CarSeeder ............................................................. RUNNING  
  Database\Seeders\CarSeeder ...................................................... 158.17 ms DONE
I hope that this article, and the last few, have helped to demystify Seeders, Fakers, and Factories for you. See you next time.

Laravel Series

Continue your Laravel Learning.

Laravel — P32: Factory with Faker

The Ultimate Laravel Pair: Factories and Faker for Dynamic Data

Laravel – P32: Factory With Faker

Combine Laravel factories with Faker for unparalleled testing data. Create dynamic, realistic environments for development & testing.

Laravel — P33: Seeders

Laravel Seeders: Planting the Seeds of Your Database

Laravel – P33: Seeders

Discover Laravel seeders for efficient database population. Learn to seed your database with data for development, testing, or staging.

Laravel — P34: Introduction to the Car Management Project

An Introduction to a Laravel Car Management Project

Laravel – P34: Car Management Project

Dive into the Car Management Project with Laravel. Get a comprehensive guide to building & managing a vehicle database efficiently.

Leave a Reply