Сидеры и фабрики для тестовых данных в Laravel: пошаговая инструкция
За полчаса вы настроите генерацию тестовых данных в Laravel 11: создадите фабрику для модели, свяжете её с сидером и наполните базу сотней записей одной командой.

К концу этой инструкции ваша локальная база будет наполнена десятками пользователей и связанных с ними постов — без ручного ввода через phpMyAdmin и без SQL-скриптов. Понадобится примерно 30–40 минут, если Laravel уже установлен. Всё делается на Laravel 11.x, но команды почти без изменений работают и в 10.x.
Разберём три вещи по порядку: фабрику (описывает, как выглядит одна фейковая запись), сидер (кладёт записи в базу) и команду, которая всё это запускает. В конце — что делать, если команда падает с ошибкой.
Что нужно иметь до начала
Проверьте, что у вас есть, прежде чем запускать команды. Если чего-то не хватает, узнаете об этом сейчас, а не на четвёртом шаге.
- PHP 8.2+ и Composer — Laravel 11 не запустится на PHP ниже 8.2.
- Установленный проект Laravel и настроенное подключение к БД в файле
.env(переменныеDB_CONNECTION,DB_DATABASEи остальные). - Применённые миграции — таблицы должны существовать. Проверьте командой
php artisan migrate:status. - Модель, для которой генерируем данные. Дальше примеры на моделях
User(идёт из коробки) иPost.
Библиотека для генерации фейковых данных fakerphp/faker1 уже входит в стандартную установку Laravel — отдельно ставить её не нужно.
Шаг 1. Создаём фабрику
Фабрика описывает, как выглядит одна «правдоподобная» запись модели. Создадим её для модели Post:
php artisan make:factory PostFactoryКоманда создаст файл database/factories/PostFactory.php. Откройте его и опишите поля модели через объект fake():
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
public function definition(): array
{
return [
// заголовок из 6 случайных слов
'title' => fake()->sentence(6),
// тело из трёх абзацев
'body' => fake()->paragraphs(3, true),
// привязываем к существующему или новому пользователю
'user_id' => User::factory(),
'published_at' => fake()->dateTimeThisYear(),
];
}
}Проверка: файл появился в database/factories/, а в методе definition() перечислены все обязательные (not null) поля вашей таблицы. Если поле в БД помечено как NOT NULL и без значения по умолчанию, оно должно быть здесь — иначе вставка упадёт.
Связываем модель с фабрикой
Чтобы вызов Post::factory() работал, модель должна использовать трейт HasFactory. В моделях, сгенерированных Laravel 11, он уже подключён. Проверьте в app/Models/Post.php:
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model
{
use HasFactory;
}Если модель и фабрика названы по соглашению (Post → PostFactory), Laravel находит фабрику автоматически. Никаких ручных регистраций не нужно.
Шаг 2. Проверяем фабрику в tinker
Прежде чем писать сидер, убедитесь, что фабрика вообще создаёт запись. Запустите интерактивную консоль:
php artisan tinkerИ выполните внутри неё:
App\Models\Post::factory()->create();Проверка: в ответ tinker выведет объект Post с заполненными полями и id. Одна строка появилась в таблице posts, ещё одна — в users (её создал вложенный User::factory()). Если вместо этого выпала ошибка — переходите к разделу «Если не получилось».
Шаг 3. Создаём сидер
Сидер — это класс, который решает, сколько записей и каких положить в базу. Создадим его:
php artisan make:seeder PostSeederВ файле database/seeders/PostSeeder.php опишите, что нужно наполнить:
<?php
namespace Database\Seeders;
use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run(): void
{
// создаём 10 пользователей, у каждого — по 5 постов
User::factory(10)
->has(Post::factory()->count(5))
->create();
}
}Метод has() создаёт связанные записи, если в модели User описано отношение posts(). Если отношения нет, используйте простой вариант без связи: Post::factory(50)->create();
Фабрика описывает форму данных, сидер — их количество и связи. Разделяйте эти роли: не задавайте в фабрике «создать 50 штук», иначе вы не сможете переиспользовать её для одной записи в тесте.
Подключаем сидер к DatabaseSeeder
Главный сидер database/seeders/DatabaseSeeder.php запускается по умолчанию. Добавьте свой в его метод run():
public function run(): void
{
$this->call([
PostSeeder::class,
]);
}Шаг 4. Наполняем базу
Запустите главный сидер:
php artisan db:seedЧтобы запустить только один конкретный сидер, минуя остальные:
php artisan db:seed --class=PostSeederЕсли хотите начать с чистой базы — сбросить все таблицы, накатить миграции заново и сразу засеять:
php artisan migrate:fresh --seedПроверка: в консоли появится строка вида INFO Seeding database. и зелёная отметка DONE. Загляните в таблицы users и posts — там должно быть 10 и 50 записей соответственно. Команда migrate:fresh сначала удаляет все данные, поэтому не запускайте её на боевой базе.
Полезные приёмы фабрик
Пара вещей, которые пригодятся почти сразу.
- Состояния (states). Опишите вариацию записи прямо в фабрике, например черновик без даты публикации:
public function draft(): static { return $this->state(['published_at' => null]); }
Вызывается какPost::factory()->draft()->create(); - Переопределение полей на лету. Передайте массив в
create()илиmake():Post::factory()->create(['title' => 'Точный заголовок']); - make() против create().
make()создаёт объект в памяти без записи в БД,create()— сохраняет. В юнит-тестах без базы беритеmake().
Если не получилось
Три ошибки, которые встречаются чаще всего.
SQLSTATE[HY000]: General error: 1364 Field 'xxx' doesn't have a default value— поле помеченоNOT NULL, но вdefinition()фабрики его нет. Добавьте это поле в фабрику.Class "Database\Factories\PostFactory" not found— фабрика названа не по соглашению или модель не в стандартном неймспейсе. Проверьте, что имя фабрики — это имя модели плюсFactory, и выполнитеcomposer dump-autoload.Call to undefined method App\Models\Post::factory()— в модели не подключён трейтHasFactory. Добавьтеuse HasFactory;внутрь класса модели.SQLSTATE[23000]: Integrity constraint violationпри повторном запуске — уникальное поле (например email) сгенерировалось дважды. Используйтеfake()->unique()->safeEmail()или сбрасывайте базу черезmigrate:fresh --seed.
Что делать дальше
Когда наполнение локальной базы заработало, следующий логичный шаг — подключить фабрики к тестам. В тестовом классе с трейтом RefreshDatabase вы будете вызывать User::factory()->create() прямо в методе теста, и база будет откатываться после каждого прогона. Инвалидация и связи многие-ко-многим через attach — отдельная тема, здесь мы её не трогали. За полным списком методов фабрик смотрите раздел Database Testing в официальной документации Laravel вашей версии.
Карточки для маркетплейсов: Таблица товаров и папка фотографий на входе — комплект слайдов и описаний на выходе, по требованиям Wildberries и Ozon.
Спросить за 5 ₽Источники: Laravel — Database: Seeding, Laravel — Eloquent: Factories
Частые вопросы
У меня Laravel 10, а не 11 — команды сработают?
Команда db:seed прошла без ошибок, но записей в базе нет. Что не так?
Можно ли запускать сидеры на боевом сервере?
Чем make() отличается от create() в фабрике?
Как сделать так, чтобы у каждого пользователя было ровно по 5 постов?
Почему при повторном запуске падает ошибка про уникальность email?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.