Граюся з Laravel Eloquent, співаючи святкову пісню.
Почнемо з клонування репозиторію, який я підготував для нас.
git clone https://github.com/ronnorthrip/twelvedays.git
Далі зайдемо в проект, встановимо залежності, скопіюємо .env і запустимо стандартні міграції.
cd twelvedays
composer install
cp .env.example .env
php artisan migrate
php artisan key:generate
Готово — можна починати. Наша задача сьогодні — зробити Laravel command, який заспіває нашу пісеньку.
php artisan make:command SingTwelveDays
Відкрийте цей файл (в app/Console/Commands) у вашому редакторі і змініть signature, description та метод handle — наразі він виводитиме лише заглушку.
protected $signature = 'sing:twelvedays';
protected $description = 'Sing the Twelve Days of Eloquent';
public function handle()
{
$this->info('The Twelve Days of Eloquent');
}
Спробуємо.
php artisan sing:twelvedays
Чудово!
Як іде ця пісня?
У перший день Eloquent
Мій фреймворк подарував мені
Куріпку на грушевому дереві
Як це реалізувати? У нас є Partridge і Pear Tree — їх можна абстрагувати як Animal і Location: тварина (partridge) має локацію (pear tree). Саме це й відображають one-to-one відносини в Eloquent. Потрібно лише вирішити, яка модель кому належить або чи буде зв'язок множинним.
Але якщо придивитися далі, рядки пісні зовсім не узгоджені — єдиною сталою лишається перший рядок. До того ж четвертий рядок ("calling birds") не відповідає порядку інших, де дія стоїть в кінці речення.
Куріпка на груші!
Дві голубки,
Три французькі курки,
Чотири співочі птахи,
П'ять золотих кілець,
Шість гусей, що несуть яйця,
Сім лебедів, що плавають,
Вісім служниць, що доять корів,
Дев'ять дам, що танцюють,
Десять лордів, що стрибають,
Одинадцять волинщиків, що грають,
Дванадцять барабанщиків, що барабанять,
Якщо розбити кожен елемент на короткі «співацькі» шматки, то найзручніше це зберігати через many-to-many polymorphic відношення — ми назвемо ці шматки 'singable'.
У такому зв'язку для кожного об'єкта (Activity, Animal, Country, Location, Person) зберігаємо id і type, щоб мати унікальне посилання. Додаємо таблицю singables у міграції.
Відкрийте файл міграції '2025_12_19_000000_create_the_tables.php' і додайте таблицю 'singables' наприкінці методу up.
Schema::create('singables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('day_id');
$table->string('singable_type');
$table->unsignedBigInteger('singable_id');
$table->timestamps();
});
Тепер збудуємо чисту базу заново:
php artisan migrate:fresh
Повертаємося до рядка пісні:
А partridge in a pear tree
Оскільки це Animal, відкрийте модель і додайте MorphToMany-відношення.
public function singable(): MorphToMany
{
return $this->morphToMany(Singable::class, 'singable');
}
Потрібно також додати зворотний метод у моделі Singable — відкрийте її й додайте MorphTo.
public function singable(): MorphTo
{
return $this->morphTo();
}
Як бачите, belongsTo-зв'язок до моделі Day уже реалізований.
Тепер можна протестувати в tinker:
php artisan tinker
$day = \App\Models\Day::create(['name'=>'First']);
$animal = \App\Models\Animal::create(['name' => 'Partidge']);
$lyric = $day->lyrics()->make();
$lyric->singable()->associate($animal)->save();
$day->lyrics()->get();
Ви побачите Eloquent Collection із прикріпленою моделлю singable з типом "App\Models\Animal".
Tinker — зручний простір для експериментів. Коли закінчите, наберіть exit або Ctrl+C.
Тепер винесемо метод singable у трейт, щоб користуватися ним у різних моделях. Поверніться в редактор, виріжте метод із моделі Animal, вставте його в CanBeSung.php і підключіть трейт у моделі Animal одразу після use HasFactory:
use CanBeSung;
До речі, цей трейт вже підключено до інших моделей, тож тепер можна створити й Location.
Після правок знову запустіть tinker і перевірте роботу:
php artisan tinker
$day = \App\Models\Day::create(['name'=>'First']);
$animal = \App\Models\Animal::create(['name' => 'Partidge']);
$location = \App\Models\Location::create(['name' => 'Pear Tree']);
$lyric1 = $day->lyrics()->make();
$lyric2 = $day->lyrics()->make();
$lyric1->singable()->associate($animal)->save();
$lyric2->singable()->associate($location)->save();
$day->lyrics()->with('singable')->get();
with підвантажує пов'язані моделі, тож у нас є всі потрібні дані — дуже зручно.
Останній рядок тут — ядро рішення: він отримує всі lyrics для дня з пов'язаними singable-об'єктами. Залишається витягти потрібне поле ('singable.name') і з'єднати їх пробілами.
Вийдіть з tinker, відкрийте модель Day і додайте метод line в кінець:
public function line(): string
{
return $this->lyrics()->with('singable')->get()->pluck('singable.name')->implode(' ');
}
Повертаємося в tinker для фінальної перевірки — дані з попередньої сесії мають бути в базі:
php artisan tinker
$day = \App\Models\Day::latest()->first();
$day->line();
Вийшло «Partridge Pear Tree»?
Чудово! Вийдіть із tinker.
Тепер відтворимо чисту базу і засіємо її даними пісні для зручної розробки:
php artisan migrate:fresh --seed
Повернулися до командного файлу SingTwelveDays.php — метод handle досі був заглушкою.
Ті частини, що треба заспівати, такі:
У перший день Eloquent
Мій фреймворк подарував мені
Куріпку на грушевому дереві
Отже: для кожного Day беремо name для першого рядка, другий рядок однаковий для всіх куплетів, а третій — результат методу line() моделі Day. Вносимо зміни і пробуємо:
public function handle()
{
\App\Models\Day::all()->each(function ($day) {
$this->info("On the ".$day->name." day of Eloquent");
$this->info("My framework gave to me");
$this->info($day->line());
$this->info("");
sleep(2);
});
}
php artisan sing:twelvedays
Ну як вам?
Бажаю найщасливіших свят, друзі Laravel
Від вашого сусіда White Beard
-Ron
Хочете забезпечити повну прозорість у своїх Laravel-додатках? Пакет Laravel Audit Log допоможе вам детально відстежувати всі зміни моделей Eloquent та відповідати вимогам регуляторів. Читайте далі, щоб дізнатися, як цей потужний інструмент може підвищити надійність вашого проєкту
Вам цікаво дізнатися, як спростити інтеграцію RabbitMQ у вашому Laravel-додатку? У нашій статті ми розглянемо пакет Simple RabbitMQ, який дозволяє легко налаштувати багатозʼєднання, публікувати повідомлення та обробляти черги за допомогою простого синтаксису. Читайте далі, щоб дізнатися більше!
Зазирніть у світ Laravel, де потужний CLI-фреймворк відкриває нові можливості для розробки командного інтерфейсу. Дізнайтеся, як створити просту утиліту для перевірки акцій, яка працює з Docker, та які переваги це може принести у вашому проєкті!