'Laravel 8 Multiple Relationships for Factory

In Laravel 8 it is possible to quickly fill relationships with factories. However, I cannot figure out how to generate more than one relationship. How can I create a random or new relationship for each link using the new Laravel 8 syntax?

This factory syntax is only available in Laravel 8. https://laravel.com/docs/8.x/database-testing#factory-relationships

Problem

Consider the following relationship:

  • Each link belongs to a website and a post.
  • Both websites and posts can have many links.
<?php

class Post extends Model
{
    use HasFactory;

    function links()
    {
        return $this->hasMany(Link::class);
    }
}

class Website extends Model
{
    use HasFactory;

    function links()
    {
        return $this->hasMany(Link::class);
    }
}

class Link extends Model
{
    use HasFactory;

    function post()
    {
        return $this->belongsTo(Post::class);
    }

    function website()
    {
        return $this->belongsTo(Website::class);
    }
}


What I tried/want

What I tried below will only generate one model for all the links. How can I create a random or new relationship for each link using the new Laravel 8 syntax?

Link::factory()->count(3)->forPost()->forWebsite()->make()

=> Illuminate\Database\Eloquent\Collection {#4354
     all: [
       App\Models\Link {#4366
         post_id: 1,
         website_id: 1,
       },
       App\Models\Link {#4395
         post_id: 1, // return a different ID
         website_id: 1,
       },
       App\Models\Link {#4370
         post_id: 1, // return a different ID
         website_id: 1, // return a different ID
       },
     ],
   }


Solution 1:[1]

Just add this to your LinkFactory:

  public function definition()
  {
    return [
        'post_id' => function () {
            return Post::factory()->create()->id;
        },

        .....
    ];
}

And now you can create new Post for each new Link:

Link::factory()->count(3)->create();//Create 3 links with 3 new posts

or attach new Links to existing Post:

Link::factory()->count(3)->create(['post_id' => Post::first()->id]); //create 3 links and 0 new posts

Solution 2:[2]

The laravel magic factory method for allows you to populate the database with one record from the foreign table. See link to documentation https://laravel.com/docs/8.x/database-testing#belongs-to-relationships

In your case, using forPost() and forWebsite() will allow you to populate the database with one id from the Post table and the Website table.

If you want to use different IDs use this syntax instead Link::factory()->count(3)->make()

Solution 3:[3]

\App\Models\Category::factory(10)
->has(Product::factory()->count(10), 'products')
->create();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andriy Lozynskiy
Solution 2 jed
Solution 3 mostafa ali