Метод afterCreating
Метод afterCreating класса Factory позволяет
выполнить дополнительные действия после того, как модель была
создана в базе данных. Первым и единственным параметром метод
принимает замыкание (callback), которое получает созданную
модель в качестве аргумента. Этот метод удобно использовать
для настройки связанных данных, выполнения побочных операций
или модификации модели после сохранения.
Синтаксис
<?php
Factory::afterCreating($callback);
?>
Пример
Давайте создадим фабрику для модели User и добавим
обработчик, который будет создавать профиль пользователя
после его регистрации:
<?php
namespace DatabaseFactories;
use AppModelsUser;
use AppModelsProfile;
use IlluminateDatabaseEloquentFactoriesFactory;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition(): array
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'password' => bcrypt('password'),
];
}
public function configure(): static
{
return $this->afterCreating(function (User $user) {
Profile::create([
'user_id' => $user->id,
'bio' => $this->faker->sentence(),
'avatar' => $this->faker->imageUrl(),
]);
});
}
}
?>
Теперь при создании пользователя через фабрику автоматически создаётся связанный профиль:
<?php
use AppModelsUser;
use AppModelsProfile;
use DatabaseFactoriesUserFactory;
$user = UserFactory::new()->create();
$profile = Profile::where('user_id', $user->id)->first();
echo $user->name;
echo $profile->bio;
?>
Результат выполнения кода:
"John Doe"
"Eum et omnis voluptate sunt."
Пример
Метод afterCreating можно использовать для создания
нескольких связанных моделей или выполнения сложной логики
после создания основной модели:
<?php
namespace DatabaseFactories;
use AppModelsPost;
use AppModelsComment;
use AppModelsTag;
use IlluminateDatabaseEloquentFactoriesFactory;
class PostFactory extends Factory
{
protected $model = Post::class;
public function definition(): array
{
return [
'title' => $this->faker->sentence(),
'content' => $this->faker->paragraphs(3, true),
'user_id' => UserFactory::new(),
];
}
public function configure(): static
{
return $this->afterCreating(function (Post $post) {
Comment::factory()->count(5)->create([
'post_id' => $post->id,
]);
Tag::factory()->count(3)->create()->each(function ($tag) use ($post) {
$post->tags()->attach($tag);
});
});
}
}
?>
После создания поста автоматически добавляются комментарии и теги:
<?php
use AppModelsPost;
use AppModelsComment;
use AppModelsTag;
use DatabaseFactoriesPostFactory;
$post = PostFactory::new()->create();
$comments = Comment::where('post_id', $post->id)->count();
$tags = $post->tags()->count();
echo $comments;
echo $tags;
?>
Результат выполнения кода:
"5"
"3"
Пример
В тестах метод afterCreating полезен для настройки
состояний модели. Создадим фабрику с разными состояниями
и дополнительной логикой:
<?php
namespace DatabaseFactories;
use AppModelsOrder;
use AppModelsOrderItem;
use IlluminateDatabaseEloquentFactoriesFactory;
class OrderFactory extends Factory
{
protected $model = Order::class;
public function definition(): array
{
return [
'user_id' => UserFactory::new(),
'total' => 0,
'status' => 'pending',
];
}
public function withItems(int $count = 3): static
{
return $this->afterCreating(function (Order $order) use ($count) {
$items = OrderItem::factory()->count($count)->create([
'order_id' => $order->id,
]);
$total = $items->sum('price');
$order->update(['total' => $total]);
});
}
public function completed(): static
{
return $this->afterCreating(function (Order $order) {
$order->update(['status' => 'completed']);
});
}
}
?>
Использование фабрики с состояниями в тесте:
<?php
namespace TestsFeature;
use TestsTestCase;
use AppModelsOrder;
use DatabaseFactoriesOrderFactory;
class OrderTest extends TestCase
{
public function test_order_creation_with_items()
{
$order = OrderFactory::new()
->withItems(5)
->completed()
->create();
$this->assertEquals(5, $order->items()->count());
$this->assertEquals('completed', $order->status);
$this->assertGreaterThan(0, $order->total);
}
}
?>
Результат выполнения кода:
"Test passed successfully"
Смотрите также
-
метод
afterMaking,
который выполняет действия после создания модели в памяти -
метод
create,
который сохраняет модель в базу данных -
метод
state,
который определяет состояние фабрики -
метод
has,
который определяет связи для фабрики