Laravel factory: Seeder sequence index not resetting in has many relationship

245 Views Asked by At

I have a seeder function that run factory like this

Product::factory()
    ->count(100)
    ->state(new Sequence(
        fn($sequence) => ['age_group_marketplace_id' => $ageGroup->random()]
    ))
    ->has(
        Media::factory(5)
            ->state(new Sequence(...self::IMAGE_LIST))
            ->state(new Sequence(
                fn ($sequence) => ['order_column' => $sequence->index]
            ))
    )
    ->create();

basically, this will create 100 product that have 5 media. But the problem is the $sequence->index will not reset to 0 after 5 media is created for the product. it will just continue until the 499

I expect it will get the index of 0, 1, 2, 3, 4 and then reset to 0 again

2

There are 2 best solutions below

0
On

I had the same problem but solved it using Factory Callbacks way;

According to the Laravel documentation: Factory callbacks are registered using the afterMaking and afterCreating methods and allow you to perform additional tasks after making or creating a model.

NB: You should register these callbacks by defining a configure method on your factory class.

In your case; you should have Product Factory separate and then call Media::Factory within the configure function of Product Factory i.e.

// Within DatabaseSeeder or ProductSeeder

Product::factory()
    ->count(100)
    ->state(new Sequence(
        fn($sequence) => ['age_group_marketplace_id' => $ageGroup->random()]
    ))
    ->create();

...

// Product Factory

public function configure(){
    return $this->afterCreating(function (Product $product) {
        Media::factory(5)->sequence(fn ($sequence) => ['order_column' => $sequence->index])->create([
            'product_id' => $product->id
        ]);
    });
}
0
On

You can try to do like this,


Product::factory()
    ->count(100)
    ->state(new Sequence(
        fn($sequence) => ['age_group_marketplace_id' => $ageGroup->random()]
    ))
    ->create()
    ->each(function ($product)
        for ($i=0; $i < 5; $i++) { 
            Media::factory()
            ->create([
                'product_id    => $product['id'],
                'order_column' => $i
            ]);
        }
    );

I have assumed the Media model to have a product_id foreign key. You can change it to something that your code needs.

This has worked for me.