Make your Laravel Seeder Using Model Factories

Make your Laravel Seeder Using Model Factories

You must have just started development of a Laravel based project and you need to fill it with data. Laravel includes a simple method of seeding your database with test data using seed classes. All seed classes are stored in the database/seeds directory...

You must have just started development of a Laravel based project and you need to fill it with data. Laravel includes a simple method of seeding your database with test data using seed classes. All seed classes are stored in the database/seeds directory...

Database Seeding is important when developing applications whether it's going to be a small app or a large scale application.

Writing Seeders and Model Factories

Table of Contents

  • Pratical Example
  • Generating Model and Migration
  • Write Migration and Model Factory
  • Generating Seeder
  • Write Database Seeder
  • Conclusion

To create a Seeder the make:seeder artisan command is executed. Read Laravel docs here for more instructions

php artisan make:seeder TestSeeder

A model Factory is generated by executing the make:factory artisan command.

php artisan make:factory PostFactory --model=Post

Read more here about using model factories in Laravel.

Pratical Example

Let's seed a simple Film sharing and commenting application, where users can share films belonging to a particular genre. So there will be a User, Film, Comment and Genre Model .

Generating Model and Migration

Laravel default comes with a User model and migration which is good enough for this example. Let's go ahead and create the other models and migration.

php artisan make:model Film -m 
 ## create film model and migration

php artisan make:model Comment -m 
 ## create comment model and migration

php artisan make:model Genre -m
 ## create genre model and migration

Write Migration and Model Factory

User migration and model factory comes prewritten … so we can skip ....

Write Genre Migration and Factory

// Genre Migration
   public function up()
    {
        Schema::create('genres', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }
php artisan make:factory GenreFactory --model=Genre
// Genre Factory
<?php

use Faker\Generator as Faker;

$factory->define(App\Genre::class, function (Faker $faker) {
    return [
        'name' => $faker->word,
    ];
});

Write Film Migration and Factory

//Film Migration 
public function up()
    {
        Schema::create('films', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id');
            $table->string('title');
            $table->text('description');
            $table->date('release_date');
            $table->enum('rating',[ 1, 2, 3, 4, 5] );
            $table->integer('genre_id');
            $table->string('photo');
            $table->string('slug');
            $table->timestamps();

        });
    }
php artisan make:factory FilmFactory --model=Film
<?php

use Faker\Generator as Faker;

$factory->define(App\Film::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence(5),
        'description' => $faker->realText(rand(80, 600)),
        'release_date'  => $faker->date(),
        'rating' => rand(1,5),
        'genre_id' => function () {
            // Get random genre id
            return App\Genre::inRandomOrder()->first()->id;
        },
        'photo'  => 'https://via.placeholder.com/350x150',
        'slug'   => str_replace('--', '-', strtolower(preg_replace('/[^a-zA-Z0-9]/', '-', trim($faker->sentence(5))))),
    ];
});

*Write Comment Migration and Factory *

// Comment Migration
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id');
            $table->integer('film_id');
            $table->text('comment');
            $table->timestamps();
        });
    }
php artisan make:factory CommentFactory --model=Comment
<?php

use Faker\Generator as Faker;

$factory->define(App\Comment::class, function (Faker $faker) {
    return  [
        'comment' => $faker->realText(rand(10, 300)),
      ];
});

Generating Seeder

Write Genre Seeder

php artisan make:seeder GenreTableSeeder
public function run()
    {
        // How many genres you need, defaulting to 10
        $count = (int)$this->command->ask('How many genres do you need ?', 10);

        $this->command->info("Creating {$count} genres.");

        // Create the Genre
        $genres = factory(App\Genre::class, $count)->create();

        $this->command->info('Genres Created!');

    }

Write User and Film Seeder

php artisan make:seeder UserFilmSeeder

Since this is a film sharing application, every user tends to share a certain number of film on this app. So our seeder should look like ....

public function run()
    {
        // How many genres you need, defaulting to 10
        $userCount = (int)$this->command->ask('How many users do you need ?', 10);

        // Ask range for film per user needed
        $r = 0 . '-' . 10;
        $filmRange = $this->command->ask('How many films per user do you need ?', $r);

        $this->command->info("Creating {$userCount} users each having a film range of {$filmRange}.");

        // Create the Users 
        $users = factory(App\User::class, $userCount)->create();

        // Create a range of films for each users
        $users->each(function($user) use ($filmRange){
            factory(App\Film::class, $this->count($filmRange))
                    ->create(['user_id' => $user->id]);
        });

        $this->command->info('Users and Films Created!');

    }

     // Return random value in given range
    function count($range)
    {
        return rand(...explode('-', $range));
    }

Write Comment Seeder

php artisan make:seeder CommentTableSeeder
public function run()
    {
        $r = 0 . '-' . 10;
        $commentRange = $this->command->ask('How many comments per film do you need ?', $r);

        $films = App\Film::all();

        $this->command->info("Creating a range of {$commentRange} comments for {$films->count()} films .");

        $films->each(function($film) use ($commentRange){
            factory(App\Comment::class, $this->count($commentRange))
                ->create([
                       'film_id' => $film->id,
                       'user_id' => App\User::all()->random()->id
                    ]);
        });

        $this->command->info('Comments Created!');

    }

      // Return random value in given range
    function count($range)
    {
        return rand(...explode('-', $range));
    }

Write Database Seeder

Let's invoke generated seeders in the DatabaseSeeder class using the call method

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{

    public function run()
    {
        Eloquent::unguard();

        // Ask for db migration refresh, default is no
        if ($this->command->confirm('Do you wish to refresh migration before seeding, it will clear all old data ?')) {

            // Call the php artisan migrate:fresh using Artisan
            $this->command->call('migrate:fresh');

            $this->command->line("Database cleared.");
        }

        $this->call(GenreTableSeeder::class);
        $this->call(UserFilmSeeder::class);
        $this->call(CommentTableSeeder::class);

        $this->command->info("Database seeded.");

        // Re Guard model
        Eloquent::reguard();

    }
}

Conclusion

If you run php artisan db:seed it will ask questions and seed the data accordingly.

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

Brave, Chrome, Firefox, Opera or Edge: Which is Better and Faster?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Clear Cache in Laravel 6.8 App using Artisan Command Interface (CLI)

In Laravel 6 tutorial, we learn how to use PHP artisan command interface (CLI) to clear the cache from Laravel 6.8 application. How To Clear Cache in Laravel 6.8 Application using Artisan Command Line Interface (CLI)? How to clear route cache using php artisan command? How to easily clear cache in Laravel application? How to clear config cache in PHP Laravel via artisan command? How to clear Laravel view cache? How to Reoptimized class in Laravel via artisan CLI?

Get Weather Data with Laravel Weather

Get Weather Data with Laravel Weather. Laravel Weather is a good package which we can use to get weather data. It's a wrapper around Open Weather Map API (Current weather). A wrapper around Open Weather Map API (Current weather)

Laravel Sweet Alert | How to use the SweetAlert package in Laravel PHP

Sweet Alert is a laravel wrapper around #sweetalert javascript library for showing alert or notification message. This is a great package created by rashid, and this laravel package is very famous because it has tonnes of features you can choose from.