Как можно создать фабрики для связанных таблиц?

Как создать фабрику для профиля с автоинкрементным значением `user_id`, чтобы избежать ошибки "два первичных ключа не могут быть в таблице" при запуске сидера?
  • 5 октября 2023 г. 18:57
Ответы на вопрос 3
Чтобы создать фабрику для связанных таблиц, вам понадобится использовать отношение `belongsTo` или `hasOne` в соответствующей фабрике.

Например, если у вас есть модели `User` и `Profile`, и каждый пользователь имеет только один профиль, вы можете создать фабрику для профиля следующим образом:

1. Создайте фабрику для модели `Profile`:

```php
// database/factories/ProfileFactory.php

use App\Models\Profile;
use App\Models\User;
use Faker\Generator as Faker;

$factory->define(Profile::class, function (Faker $faker) {
    return [
        'user_id' => function () {
            return factory(User::class)->create()->id;
        },
        // Другие атрибуты профиля
    ];
});
```

2. Создайте фабрику для модели `User` и свяжите ее с фабрикой `Profile` с помощью отношения `hasOne`:

```php
// database/factories/UserFactory.php

use App\Models\User;
use Faker\Generator as Faker;

$factory->define(User::class, function (Faker $faker) {
    return [
        // Атрибуты пользователя
    ];
})->afterCreating(User::class, function ($user, $faker) {
    $user->profile()->save(factory(Profile::class)->make());
});
```

Теперь, когда вы будете вызывать фабрику для модели `User` с помощью `factory(User::class)->create()`, она автоматически создаст связанный профиль с автоинкрементным значением `user_id`.

Это позволит вам избежать ошибки "два первичных ключа не могут быть в таблице", так как создание профиля будет происходить после создания пользователя.
Return new profile with automatically created user
class ProfilFactory extends Factory
{
    public function definition(): array
    {
        return [
            'user_id' => User::factory()->create(),
            // ...
        ];
    }
}
Похожие вопросы