skip to Main Content

I’m creating "Foo" models using a Laravel 10 factory. I want each model Foo to have a belongsTo relationship to a random already existing model "Bar". There is no factory for Bar and I want to minimize the number of database queries.

I found a simple solution but it required to fetch all the Bar models for every created Foo and I wanted to avoid unnecessary queries.

The only way I found is to use states with the Bar models collection :

$bars = Bar::all();

Foo::factory()
    ->count(3)
    ->state(function () use ($bars) {
        return ['bar_id' => $bars->random()->id];
    })

Isn’t there a simpler way to do it?

2

Answers


  1. In Laravel, you can achieve this by using a closure in your factory state. However, since you want to minimize the number of database queries, you can first fetch all the Bar models and then use a closure to select a random Bar from the collection for each Foo you create. Here’s how you can do it:

    $bars = Bar::all();
    
    Foo::factory()
        ->count(3)
        ->state(function (array $attributes) use ($bars) {
            return [
                'bar_id' => $bars->random()->id,
                // Other attributes for Foo if needed
            ];
        })
        ->create();
    

    This code fetches all the Bar models and then, for each Foo being created, selects a random Bar from the collection without any additional database queries. This approach minimizes the number of queries and achieves your desired result of having each Foo model belong to a random Bar model.

    Login or Signup to reply.
  2. you can solve this issue by generating random bar_id values within the factory itself. Here’s how you can do it:

    Foo::factory()
        ->count(3)
        ->create([
            'bar_id' => function () {
                return Bar::inRandomOrder()->first()->id;
            },
        ]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search