Get "PHP 8 in a Nuthshell" (Soon includes PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Insert mass database records using model factories in Laravel

One of the many ways using which you can insert records (or seed your database) is by using the seeder classes which extend a base class called Illuminate\Database\Seeder in Laravel.

For instance, if you want a seeder for say books table, you can generate it using the following command like so.

$ php artisan make:seeder BookSeeder

This will generate the seeder class under the database/seeds directory which looks like the following.

<?php

use Illuminate\Database\Seeder;

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

Now, the class only contains a method called run and this is where you can write queries to insert records like so.

public function run()
{
    DB::table('books')->insert([
            'name' => Str::random(10),
            'author' => Str::random(10),
            'type' => Str::random(10),
        ]);
}

Now, whenever you run the seeders, it will add a record in the books table with random values as shown above. This alright but what if you want more records for your testing purposes? You certainly won’t repeat multiple insert queries inside of the run, right?

And this is where model factories come into the picture.

Model Factories

In a nutshell, model factories are nothing but PHP files (not classes) using which Laravel allows you to set a default set of attributes for each of your Eloquent models.

A factory can be generated by using make:factory Artisan command. So, if we want to generate a factory for our Book model, we can generate it like so.

$ php artisan make:factory BookFactory

This will generate a PHP file called BookFactory.php under database/factories directory and it would look like so.

<?php

use App\Book;
use Illuminate\Support\Str;
use Faker\Generator as Faker;

$factory->define(Book::class, function (Faker $faker) {
    $type = ['fiction', 'nonfiction'];

    return [
        'name' => $faker->word,
        'author' => $faker->name,
        'type' => $type[rand(0, (count($type)-1))]
    ];
});

As you can see, Laravel gives us Faker PHP library at our disposal in the factory definition which is a Closure. Here, we can set the default values for attributes by returning an attributes array using the Faker library. Once done, we can now use this factory as a base to our BookSeeder which will generate database records using factory definition.

For instance, if you want to generate, say 20 records based on this factory, you can use it in the BookSeeder like so.

public function run()
{
    factory(App\Book::class, 20)->create()->each(function ($book) {
        $book->save(factory(App\Book::class)->make());
    });
}

This will generate 20 records for the books table without cluttering your code too much and is also easy to maintain.

Of course, you can also attach a relationship over here. So, if we want to attach a sales relationship, you can do it like so.

$book->sales()->save(factory(App\Book::class)->make());
Learn the fundamentals of PHP 8 (including 8.1, 8.2, and 8.3), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?