'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 |