Урок 08

Фабрики моделей

Фабрика — это класс, который генерирует тестовые данные для модели. Фабрики используются в тестах и сидерах, чтобы быстро создать много реалистичных записей.

Создание

php artisan make:factory PostFactory

Файл database/factories/PostFactory.php.

Пример фабрики

namespace Database\Factories;

use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition(): array
    {
        return [
            'title' => fake()->sentence(),
            'body' => fake()->paragraphs(3, true),
            'slug' => fake()->slug(),
            'published' => fake()->boolean(70),
            'user_id' => User::factory(),
            'published_at' => fake()->dateTimeBetween('-1 year', 'now'),
        ];
    }
}

Использование

Post::factory()->create();
Post::factory()->count(10)->create();

Post::factory()->make(); // без сохранения в БД

Состояния

Если нужны вариации:

public function published(): static
{
    return $this->state(fn (array $attributes) => [
        'published' => true,
    ]);
}

public function draft(): static
{
    return $this->state(fn (array $attributes) => [
        'published' => false,
    ]);
}

Использование:

Post::factory()->published()->count(5)->create();

Наследование

public function configure(): static
{
    return $this->afterCreating(function (Post $post) {
        // действия после создания
    });
}

Связи

'user_id' => User::factory(),

Создаст нового пользователя для каждого поста. Если нужно использовать существующих:

'user_id' => User::inRandomOrder()->first()->id,

Переопределение

Post::factory()->create([
    'title' => 'Кастомный заголовок',
]);

Использование в сидере

public function run(): void
{
    Post::factory()->count(50)->create();
}

Fake

fake() — хелпер для Faker. Полезные методы:

  • fake()->name()
  • fake()->email()
  • fake()->sentence()
  • fake()->paragraph()
  • fake()->dateTimeBetween('-1 year')
  • fake()->boolean(70) — 70% true
  • fake()->randomElement(['a', 'b', 'c'])
  • fake()->numberBetween(1, 100)
  • fake()->uuid()