Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jrdavidson's avatar

Closure Inside of a model factory

I'm trying to figure out why I'm getting the following error.

  1. Tests\Unit\WrestlerTest::it_can_get_injured_wrestlers ErrorException: Undefined index: id.
/** @test */
    public function it_can_get_injured_wrestlers()
    {
        $wrestler = factory(Wrestler::class)->states('injured')->create();

        $injuredWrestlers = Wrestler::injured()->get();

        $this->assertTrue($injuredWrestlers->contains($wrestler));
    }

$factory->state(App\Wrestler::class, 'injured', function ($faker) {
    return [
        'status_id' => function(array $wrestler) {
            factory(App\WrestlerInjury::class)->create([
                'wrestler_id' => $wrestler['id']
            ]);

            return 3;
        },
    ];
});
<?php

use App\Wrestler;
use App\WrestlerBio;
use Illuminate\Database\Seeder;

class WrestlersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for($i = 115; $i <= 120; $i++)
        {
            $wrestler = factory(Wrestler::class)->states('injured')->create(['name' => 'Wrestler '. $i, 'slug' => 'wrestler'.$i]);

            $wrestler->bio()->save(factory(WrestlerBio::class)->create(['wrestler_id' => $wrestler->id, 'signature_move' => 'Signature Move '.$i]));
        }
    }
}

<?php

use App\Wrestler;
use App\WrestlerInjury;
use Carbon\Carbon;
use Illuminate\Database\Seeder;

class WrestlersInjuriesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $wrestlers = Wrestler::get(['id', 'hired_at'])->random(50);

        foreach($wrestlers as $wrestler)
        {
            factory(WrestlerInjury::class)->create([
                'wrestler_id' => $wrestler->id,
                'injured_at' => function() use ($wrestler) {
                    return Carbon::parse($wrestler->hired_at)->addDays(30);
                },
                'healed_at' => function(array $injury) {
                    return Carbon::parse($injury['injured_at'])->addDays(30);
                }
            ]);
        }

        $injuredWrestlerIds = Wrestler::where('status_id', 3)->get()->pluck('id');

        foreach($injuredWrestlerIds as $wrestlerId)
        {
            factory(WrestlerInjury::class)->create(['wrestler_id' => $wrestlerId, 'healed_at' => null]);
        }
    }
}

0 likes
3 replies
epixian's avatar

In your factory, what if you typehint $wrestler instead to Wrestler $wrestlerin the closure and use object notation $wrestler->id instead?

    return [
        'status_id' => function(Wrestler $wrestler) {
            factory(App\WrestlerInjury::class)->create([
                'wrestler_id' => $wrestler->id
            ]);

            return 3;
        },
    ];
});```
martinbean's avatar

@xtremer360 Is it not because you’re trying to get the ID of a wrestler, inside a wrestler factory, before that factory’s actually created the wrestler in the database? You can’t get the ID of a record that doesn’t exist yet.

Please or to participate in this conversation.