Updated Answer
If you don't care about controlling which morphable model is created:
public function definition()
{
return [
'content' => $this->faker->paragraph(),
'noteable_id' => function (array $attributes) {
return $attributes['noteable_type']::factory();
}),
'noteable_type' => $this->faker->randomElement([
Complex::factory(),
User::factory()
]),
'title' => $this->faker->sentence()
];
}
Original answer
I have another solution that does not imply the use of the randomElement
, which is good by the way, but can be problematic when you need control on the morphable model that is being created. You still need to create model factories for the Note
, User
and Complex
models. Then the run
method of the Databaseeder
class would look like this:
public function run()
{
$userNotes = Note::factory()->count(10)->for(
User::factory(), 'noteable'
)->create();
$complexNotes = Note::factory()->count(10)->for(
Complex::factory(), 'noteable'
)->create();
}
There is another approach by using the factory states. You still need to define model factories for your 3 models. Additionally you define two state transformation methods in the NoteFactory
class.
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class NoteFactory extends Factory
{
public function definition()
{
return [
'content' => $this->faker->paragraph(),
'title' => $this->faker->sentence()
];
}
public function forComplex()
{
return $this->state(function (array $attributes) {
return [
'noteable_type' => Complex::class,
'noteable_id' => Complex::factory()
];
});
}
public function forUser()
{
return $this->state(function (array $attributes) {
return [
'noteable_type' => User::class,
'noteable_id' => User::factory()
];
});
}
}
In this case the Databaseeder
class run
method would look like this:
public function run()
{
$userNotes = Note::factory()->count(10)->forUser()->create();
$complexNotes = Note::factory()->count(10)->forComplex()->create();
}