Master Data Generation with Laravel Seeders and Factories
PersonalCarBrand Seeder
Our PersonalCarBrand
model contains a name
and a slug
. Whenever we’re seeding the database, we don’t need to seed accurate information. In other words, it doesn’t matter if we seed the tables with Lamborghini
and Ferrari
. Each of these are just strings, so we’ll just create some strings and seed them.
First, we need to populate our PersonalCarBrandFactory
.
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\PersonalCarBrand>
*/
class PersonalCarBrandFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => ucfirst( $word = $this->faker->unique()->word() ),
'slug' => $word,
];
}
}
The factory just creates a word and then uses that same word for the slug
. The unique()
method is there to try and generate a unique word for you. Sometimes it won’t work, especially if you’re trying to create large datasets. Also, if you have data already populated in your database, it’ll likely break. That’s why I recommend that you migrate:fresh
when you have unique columns in your tables.
The factory can now be added to our PersonalCarBrandSeeder
.
<?php
namespace Database\Seeders;
use App\Models\PersonalCarBrand;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PersonalCarBrandSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
PersonalCarBrand::factory()->count(10)->create();
}
}
The seeder will generate 10 rows inside of our personal_car_brands
table. We just need to add our seeder now to our DatabaseSeeder
class and run the seeders.
<?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,
PersonalCarBrandSeeder::class,
]);
}
}
PersonalCarBrandSeeder
under those two. Run the command:php artisan db:seed
Sometimes it’s better to rerun all your migrations and seed during that time.
php artisan migrate:fresh --seed
Check your table. It should have some content there.
# php artisan db:seed
INFO Seeding database.
Database\Seeders\UserSeeder .............................................................................................................. RUNNING
Database\Seeders\UserSeeder ....................................................................................................... 103.86 ms DONE
Database\Seeders\CarSeeder ............................................................................................................... RUNNING
Database\Seeders\CarSeeder ........................................................................................................ 105.51 ms DONE
Database\Seeders\PersonalCarBrandSeeder .................................................................................................. RUNNING
Database\Seeders\PersonalCarBrandSeeder ............................................................................................ 24.16 ms DONE
mysql> select * from personal_car_brands;
+----+---------+---------+---------------------+---------------------+
| id | name | slug | created_at | updated_at |
+----+---------+---------+---------------------+---------------------+
| 1 | Qui | qui | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 2 | Maiores | maiores | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 3 | Quod | quod | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 4 | Sint | sint | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 5 | Sit | sit | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 6 | Ut | ut | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 7 | Nam | nam | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 8 | Et | et | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 9 | Aut | aut | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
| 10 | Fugit | fugit | 2023-01-20 20:07:43 | 2023-01-20 20:07:43 |
+----+---------+---------+---------------------+---------------------+
10 rows in set (0.00 sec)
PersonalCarModel Seeder
It’s almost unnecessary to illustrate this concept since it’s almost identical. We’ll create the factory, add it to our seeder, add our seeder to the DatabaseSeeder
and run the db:seed
command.
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\PersonalCarModel>
*/
class PersonalCarModelFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => ucfirst( $word = $this->faker->unique()->word() ),
'slug' => $word,
];
}
}
<?php
namespace Database\Seeders;
use App\Models\PersonalCarModel;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PersonalCarModelSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
PersonalCarModel::factory()->count(10)->create();
}
}
<?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,
PersonalCarBrandSeeder::class,
PersonalCarModelSeeder::class,
]);
}
}
# php artisan migrate:fresh --seed
Dropping all tables .................................................................................................................... 81ms DONE
INFO Preparing database.
Creating migration table ............................................................................................................... 17ms DONE
INFO Running migrations.
2014_10_12_000000_create_users_table ................................................................................................... 27ms DONE
2014_10_12_100000_create_password_resets_table ......................................................................................... 23ms DONE
2019_08_19_000000_create_failed_jobs_table ............................................................................................. 25ms DONE
2019_12_14_000001_create_personal_access_tokens_table .................................................................................. 38ms DONE
2023_01_12_185409_create_tests_table ................................................................................................... 26ms DONE
2023_01_12_194511_add_phone_to_tests_table ............................................................................................. 11ms DONE
2023_01_16_162646_create_cars_table .................................................................................................... 14ms DONE
2023_01_19_194202_create_personal_car_brands_table ..................................................................................... 34ms DONE
2023_01_19_194203_create_personal_car_models_table ..................................................................................... 35ms DONE
2023_01_19_194255_create_personal_cars_table ........................................................................................... 15ms DONE
2023_01_19_194540_create_images_table .................................................................................................. 14ms DONE
2023_01_19_194631_create_image_personal_car_table ...................................................................................... 13ms DONE
INFO Seeding database.
Database\Seeders\UserSeeder .............................................................................................................. RUNNING
Database\Seeders\UserSeeder ........................................................................................................ 85.86 ms DONE
Database\Seeders\CarSeeder ............................................................................................................... RUNNING
Database\Seeders\CarSeeder ........................................................................................................ 121.03 ms DONE
Database\Seeders\PersonalCarBrandSeeder .................................................................................................. RUNNING
Database\Seeders\PersonalCarBrandSeeder ............................................................................................ 30.66 ms DONE
Database\Seeders\PersonalCarModelSeeder .................................................................................................. RUNNING
Database\Seeders\PersonalCarModelSeeder ............................................................................................ 28.11 ms DONE
mysql> select * from personal_car_models;
+----+------------+------------+---------------------+---------------------+
| id | name | slug | created_at | updated_at |
+----+------------+------------+---------------------+---------------------+
| 1 | Qui | qui | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 2 | Ratione | ratione | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 3 | Aliquam | aliquam | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 4 | Ut | ut | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 5 | Et | et | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 6 | Sed | sed | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 7 | Corporis | corporis | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 8 | Laboriosam | laboriosam | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 9 | Quo | quo | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
| 10 | Voluptates | voluptates | 2023-01-20 20:20:58 | 2023-01-20 20:20:58 |
+----+------------+------------+---------------------+---------------------+
10 rows in set (0.00 sec)
PersonalCar Seeder
The PersonalCarFactory
is slightly different since it relies on data from the other tables. We could just assign a static id, and many developer do, but we’ll utilize the eloquent model to get us a random row.
<?php
namespace Database\Factories;
use App\Models\PersonalCarBrand;
use App\Models\PersonalCarModel;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\PersonalCar>
*/
class PersonalCarFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'year' => $this->faker->year(),
'personal_car_brand_id' => PersonalCarBrand::inRandomOrder()->first()->id,
'personal_car_model_id' => PersonalCarModel::inRandomOrder()->first()->id,
'is_manual' => $this->faker->boolean,
'exterior_color' => $this->faker->word(),
'purchase_amount' => $this->faker->randomNumber(8),
'current_value' => $this->faker->randomNumber(9),
'sales_amount' => 0,
'date_purchased' => $this->faker->date(),
];
}
}
The year
is pretty straightforward. The two foreign id’s for the brand and the model, utilize each model. First, we sort the table in random order (inRandomOrder
), return the first()
instance and then select the id
. This will give us a random brand and model id. All of the other fields are straightforward.
You might have noticed that in the previous article we also had date_sold
. Since it contains a default value of null
, it’s not required for us to define it inside of our factory. We can simply rely on MySQL to do it for us.
Everything else is the same as before. Add the factory to the seeder, the seeder to the DatabaseSeeder
and run your seed command.
<?php
namespace Database\Seeders;
use App\Models\PersonalCar;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PersonalCarSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
PersonalCar::factory()->count(10)->create();
}
}
<?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,
PersonalCarBrandSeeder::class,
PersonalCarModelSeeder::class,
PersonalCarSeeder::class,
]);
}
}
# php artisan migrate:fresh --seed
Dropping all tables .................................................................................................................... 83ms DONE
INFO Preparing database.
Creating migration table ............................................................................................................... 17ms DONE
INFO Running migrations.
2014_10_12_000000_create_users_table ................................................................................................... 28ms DONE
2014_10_12_100000_create_password_resets_table ......................................................................................... 24ms DONE
2019_08_19_000000_create_failed_jobs_table ............................................................................................. 25ms DONE
2019_12_14_000001_create_personal_access_tokens_table .................................................................................. 36ms DONE
2023_01_12_185409_create_tests_table ................................................................................................... 25ms DONE
2023_01_12_194511_add_phone_to_tests_table ............................................................................................. 11ms DONE
2023_01_16_162646_create_cars_table .................................................................................................... 14ms DONE
2023_01_19_194202_create_personal_car_brands_table ..................................................................................... 35ms DONE
2023_01_19_194203_create_personal_car_models_table ..................................................................................... 31ms DONE
2023_01_19_194255_create_personal_cars_table ........................................................................................... 13ms DONE
2023_01_19_194540_create_images_table .................................................................................................. 14ms DONE
2023_01_19_194631_create_image_personal_car_table ...................................................................................... 12ms DONE
INFO Seeding database.
Database\Seeders\UserSeeder .............................................................................................................. RUNNING
Database\Seeders\UserSeeder ........................................................................................................ 94.26 ms DONE
Database\Seeders\CarSeeder ............................................................................................................... RUNNING
Database\Seeders\CarSeeder ........................................................................................................ 117.66 ms DONE
Database\Seeders\PersonalCarBrandSeeder .................................................................................................. RUNNING
Database\Seeders\PersonalCarBrandSeeder ............................................................................................ 23.60 ms DONE
Database\Seeders\PersonalCarModelSeeder .................................................................................................. RUNNING
Database\Seeders\PersonalCarModelSeeder ............................................................................................ 24.50 ms DONE
Database\Seeders\PersonalCarSeeder ....................................................................................................... RUNNING
Database\Seeders\PersonalCarSeeder ................................................................................................. 43.80 ms DONE
#
mysql> select * from personal_cars;
+----+------+-----------------------+-----------------------+-----------+----------------+-----------------+---------------+--------------+----------------+-----------+---------------------+---------------------+
| id | year | personal_car_brand_id | personal_car_model_id | is_manual | exterior_color | purchase_amount | current_value | sales_amount | date_purchased | date_sold | created_at | updated_at |
+----+------+-----------------------+-----------------------+-----------+----------------+-----------------+---------------+--------------+----------------+-----------+---------------------+---------------------+
| 1 | 2022 | 6 | 6 | 1 | itaque | 21846038 | 635120796 | 0 | 2014-01-18 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 2 | 1999 | 9 | 2 | 0 | sequi | 44511427 | 697656828 | 0 | 1995-04-23 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 3 | 1991 | 9 | 2 | 0 | incidunt | 23012254 | 882379214 | 0 | 1987-09-07 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 4 | 2018 | 3 | 1 | 0 | mollitia | 47028382 | 285870699 | 0 | 1985-05-25 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 5 | 1991 | 7 | 10 | 0 | tempora | 28457362 | 720832497 | 0 | 1984-05-10 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 6 | 2014 | 8 | 4 | 1 | id | 64666626 | 707879572 | 0 | 1980-12-25 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 7 | 1986 | 4 | 9 | 0 | qui | 36442230 | 410003910 | 0 | 1977-07-06 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 8 | 1974 | 7 | 4 | 1 | tenetur | 2236172 | 779288418 | 0 | 1979-07-15 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 9 | 1971 | 8 | 6 | 0 | voluptate | 75415740 | 575873464 | 0 | 1997-10-14 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
| 10 | 1992 | 10 | 4 | 0 | mollitia | 26363032 | 806291570 | 0 | 1987-07-11 | NULL | 2023-01-20 20:37:11 | 2023-01-20 20:37:11 |
+----+------+-----------------------+-----------------------+-----------+----------------+-----------------+---------------+--------------+----------------+-----------+---------------------+---------------------+
10 rows in set (0.00 sec)
mysql>
tinker
to verify that these relationships work. We’ll do that in the next article.Laravel Series
Continue your Laravel Learning.
Setting the Stage: Database Configuration for the Car Management Project
Laravel – P35: Database Setup (CMP)
Prepare your CMP with Laravel: A step-by-step guide to setting up your database. Ensure a solid foundation for your vehicle management app.
Master Data Generation with Laravel Seeders and Factories
Laravel — P36: Seeders and Factories (CMP)
Learn how to efficiently use Laravel seeders and factories for data generation in your projects. Boost productivity and streamline your workflow.
Mastering Models in Laravel: $fillable, belongsTo, and hasMany
Laravel – P37: CMP – Models $Fillable, Belongsto and Hasmany
Explore Laravel models with a focus on $fillable, belongsTo, and hasMany. Understand how to efficiently manage relationships and data handling in your projects.