База даних: наповнення
Вступ
Laravel уміє наповнювати вашу базу даних тестовими даними за допомогою класів-сідерів (seeder). Усі класи сідерів зберігаються в каталозі database/seeders. За замовчуванням для вас уже визначено клас DatabaseSeeder. З нього ви можете методом call запускати інші класи сідерів і таким чином керувати порядком наповнення.
Під час наповнення бази даних захист від масового призначення автоматично вимикається.
Написання сідерів
Щоб згенерувати сідер, виконайте artisan-команду make:seeder. Усі згенеровані фреймворком сідери потраплять до каталогу database/seeders:
php artisan make:seeder UserSeeder
За замовчуванням клас сідера містить лише один метод - run. Він викликається при виконанні artisan-команди db:seed. Усередині методу run ви можете наповнювати базу даних як завгодно: вручну вставляти дані через конструктор запитів або скористатися фабриками моделей Eloquent.
Наприклад, змінімо стандартний клас DatabaseSeeder і додаймо до методу run вставку даних:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeders.
*/
public function run(): void
{
DB::table('users')->insert([
'name' => Str::random(10),
'email' => Str::random(10).'@example.com',
'password' => Hash::make('password'),
]);
}
}
У сигнатурі методу
runви можете вказати типи будь-яких потрібних вам залежностей. Laravel автоматично отримає їх із сервіс-контейнера.
Використання фабрик моделей
Звісно, вручну задавати атрибути для кожної моделі - марудна робота. Замість цього ви можете скористатися фабриками моделей, щоб зручно згенерувати велику кількість записів. Спершу перегляньте документацію з фабрик моделей, щоб дізнатися, як їх описувати.
Наприклад, створімо 50 користувачів, кожен із яких має один пов'язаний пост:
use App\Models\User;
/**
* Run the database seeders.
*/
public function run(): void
{
User::factory()
->count(50)
->hasPosts(1)
->create();
}
Виклик додаткових сідерів
Усередині класу DatabaseSeeder ви можете методом call запускати додаткові класи сідерів. Метод call дозволяє розбити наповнення бази на кілька файлів, щоб жоден клас сідера не розростався надміру. Він приймає масив класів сідерів, які потрібно виконати:
/**
* Run the database seeders.
*/
public function run(): void
{
$this->call([
UserSeeder::class,
PostSeeder::class,
CommentSeeder::class,
]);
}
Вимкнення подій моделей
Під час наповнення бази ви можете захотіти, щоб моделі не надсилали події. Цього можна досягти за допомогою трейта WithoutModelEvents. Трейт WithoutModelEvents гарантує, що жодної події моделі не буде надіслано, навіть якщо через метод call виконуються додаткові класи сідерів:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
class DatabaseSeeder extends Seeder
{
use WithoutModelEvents;
/**
* Run the database seeders.
*/
public function run(): void
{
$this->call([
UserSeeder::class,
]);
}
}
Запуск сідерів
Щоб наповнити базу даних, виконайте artisan-команду db:seed. За замовчуванням команда db:seed запускає клас Database\Seeders\DatabaseSeeder, який, своєю чергою, може викликати інші класи сідерів. Втім, опцією --class ви можете вказати конкретний клас сідера, який слід запустити окремо:
php artisan db:seed
php artisan db:seed --class=UserSeeder
Ви також можете наповнити базу даних командою migrate:fresh з опцією --seed: вона видалить усі таблиці та повторно виконає всі ваші міграції. Ця команда стане в пригоді, коли треба повністю перебудувати базу даних. Опцією --seeder можна вказати конкретний сідер, який слід запустити:
php artisan migrate:fresh --seed
php artisan migrate:fresh --seed --seeder=UserSeeder
Примусовий запуск сідерів на продакшні
Деякі операції наповнення можуть змінити або знищити дані. Щоб убезпечити вас від запуску таких команд на продакшн-базі, у середовищі production Laravel запитає підтвердження, перш ніж виконати сідери. Щоб запустити сідери без запитання, скористайтеся прапорцем --force:
php artisan db:seed --force