Jonathan
Jonathan

Reputation: 43

Laravel 6: db:seed multiple seeding in user

I have following factories and seeders.

Factories

Seeders

UserFactory.php


    $factory->define(App\User::class, function (Faker $faker) {
        return [
            'name' => $faker->name,
            'email' => $faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    });

ThreadFactory.php


    $factory->define(App\Thread::class, function (Faker $faker) {
        return [
            'user_id' => function() {
                return factory(App\User::class)->create()->id;
            },
            'title' => $faker->sentence,
            'body'  => $faker->paragraph
        ];
    });

ReplyFactory.php


    $factory->define(App\Reply::class, function (Faker $faker) {
        return [

            'user_id' => function() {
                return factory(App\User::class)->create()->id;
            },

            'thread_id' => function() {
                return factory(App\Thread::class)->create()->id;
            },

            'body' => $faker->paragraph
        ];
    });

UsersTableSeeder.php


    public function run()
        {
            factory(App\User::class, 50)->create();
        }

ThreadTableSeeder.php


    public function run()
        {
            factory(App\Thread::class, 50)->create()->each(function ($thread) {
                factory(App\Reply::class, 10)->create(['thread_id' => $thread->id]);
            });
        }

RepliesTableSeeder.php


    public function run()
        {
         // nothing in here . . .   
        }

DatabaseSeeder.php


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

My problem is when running the following command, I got 550 users row in user table but other two tables are right.

php artisan db:seed

So, what's going on here? I'm using Laravel 6.4.1.

Upvotes: 1

Views: 5276

Answers (2)

Yves Kipondo
Yves Kipondo

Reputation: 5603

That is because when you define the Thread factory for each Thread it create a new user which is attached to that thread. What you should do is to create just one Seeder which will create user, and for each user create threads and Replies

public function run()
{
    factory(App\User::class, 50)->create()->each(function($user) {
        factory(App\Thread::class, 50)->create(['user_id' => $user->id])
            ->each(function($thread) use ($user){
                factory(App\Reply::class, 10)->create([
                    'user_id' => $user->id, 
                    'thread_id' => $thread->id
                ]);
            });
        });
    });
}
  • Start with the creation of 50 users
  • For each users create 50 Threads and set the user_id key equal to the user which is create
  • Than for each thread create 10 replies and set user_id and thread_id to User and Thread which have just been create

Upvotes: 0

Tamim
Tamim

Reputation: 1036

According to your code for every thread, one user being created. For every reply one user being created. So for 50 thread and 10 reply in each thread, around 50x10=500 users should create. Also in your user seeder class, you are creating 50 users, that's sum up 550 users naturally.

Now if you want to keep your users low, instead of creating a new user for every thread / reply, you could randomly fetch user from database and assign. Here is an example

ThreadFactory

    $factory->define(App\Thread::class, function (Faker $faker) {
        return [
            'user_id' => \App\User::all()->random()->id,
            'title' => $faker->sentence,
            'body'  => $faker->paragraph
        ];
    });

ReplyFactory

    $factory->define(App\Reply::class, function (Faker $faker) {
        return [

            'user_id' => \App\User::all()->random()->id,

            'thread_id' => function() {
                return factory(App\Thread::class)->create()->id;
            },

            'body' => $faker->paragraph
        ];
    });

To make this working you will have to seed user table first with any number of user you want.

Upvotes: 3

Related Questions