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

Antonella's avatar

factory two functions in one

i have two fields in the poll table:

$table->id(); $table->text('status'); $table->timestamps();

status field can have three values A, B, C.

I would like to make a factory that first creates the tuples with status = A, then status = B etc.

if do factory (10)->create (); it creates me 10 tuples with status = A and 10 with status = B

how could I write the function public function definition() in factory ?

0 likes
8 replies
GeordieJackson's avatar

Can't you just use:

Poll::factory()->count(10)->make(['status' => 'A']);
Poll::factory()->count(10)->make(['status' => 'B']);
Poll::factory()->count(10)->make(['status' => 'C']);

Or are you after something else?

automica's avatar

@gianmarx so are you after something that does this:

you want 15

you get 10 where status = A
&
you get 5 where status = B

you want 22

you get 10 where status = A
&
you get 10 where status = B
&
you get 2 where status = C

that's different to how you've described it, but I think that's what you mean

Antonella's avatar

I would like to do it with only one command line and then the dates for status = A are different from those of B.

for one I'd do that:

    return [
        'status' => "A'',
            'created_at'=> now()->addDay(-3),
    ];

while for the other I would do:

    return [
        'status' => "B',
            'created_at'=> now(),
    ];
automica's avatar

@gianmarx i'm trying to understand how many you are after.

Also, how do you get status = C (for example)?

automica's avatar

@gianmarx this should do the logic, if you create the method in your test class.

function make(int $number)
{
    for ($n = 1; $n <= $number; $n++) {

        if ($n < 10) {
            $fields = [
                'status' => 'A',
                'created_at' => now()->addDay(-3)
            ];
        };
        if ($n > 9 && $n < 20) {
            $fields = [
                'status' => 'B',
                'created_at' => now()
            ];
        }
        if ($n > 19) {
            $fields = [
                'status' => 'C',
                'created_at' => now()
            ];
        }

        Model::factory($number)->create($fields);
    }
}

I'm not sure how to get that into your factory so its runnable by command line but hopefully it should get you slightly further along your quest.

@sinnbeck care to be tagged in for this question?

Antonella's avatar

what I was wondering if there was a way to do everything inside the factory and then launch everything from a single command line with tinker.

automica's avatar

@gianmarx yeah. I figured that's what you were looking to do.

if you are setting up data for your tests, then you'd be able to add this method to a seeder which would do what you're doing via tinker.

I've not got as far as extending factory methods yet. Hopefully someone else can fill in that gap for both of us.

1 like

Please or to participate in this conversation.