<? phpukraine ДОКУМЕНТАЦІЯ
Пошук по платформі
Документація українською

Переклад силами спільноти. Кожен розділ показує стан готовності — недоперекладене відкрито помічене, а не приховане.

ВЕРСІЯ
АКТУАЛЬНА Актуальний реліз. Переклад наздоганяє оригінал — розділи з низьким відсотком позначені у змісті.
ELOQUENT · ЧАСТКОВО частковий переклад, оновлено 4 вересня 2026

Початок роботи — Laravel

ПЕРЕКЛАД НЕПОВНИЙ

Частину підрозділів ще не перекладено — вони показані англійською нижче в тексті або лишились в оригіналі. Готові фрагменти вже перевірені редактором.

Laravel містить Eloquent — обʼєктно-реляційний маппер (object-relational mapper, ORM), який робить взаємодію з базою даних приємною. Коли ви використовуєте Eloquent, кожна таблиця бази даних має відповідну «Модель», що використовується для взаємодії з цією таблицею. Крім вибірки записів із таблиці бази даних, моделі Eloquent дозволяють також вставляти, оновлювати та видаляти записи з таблиці.

Примітка Перш ніж почати, обовʼязково налаштуйте зʼєднання з базою даних у конфігураційному файлі config/database.php вашого застосунку. Докладніше про налаштування бази даних дивіться в документації з конфігурації бази даних.

Генерація класів моделей

Для початку створімо модель Eloquent. Моделі зазвичай лежать у теці app\Models і розширюють клас Illuminate\Database\Eloquent\Model. Ви можете скористатися Artisan-командою make:model, щоб згенерувати нову модель:

php artisan make:model Flight

Якщо ви хочете згенерувати міграцію бази даних разом із моделлю, використайте опцію --migration або -m:

php artisan make:model Flight --migration

Під час генерації моделі можна згенерувати й різні інші типи класів: фабрики, сідери, політики, контролери та form request. Крім того, ці опції можна комбінувати, щоб створити кілька класів одразу:

# Згенерувати модель і клас FlightFactory...
php artisan make:model Flight --factory
php artisan make:model Flight -f

# Згенерувати модель і клас FlightSeeder...
php artisan make:model Flight --seed
php artisan make:model Flight -s

# Згенерувати модель і клас FlightController...
php artisan make:model Flight --controller
php artisan make:model Flight -c

# Згенерувати модель, ресурсний клас FlightController і класи form request...
php artisan make:model Flight --controller --resource --requests
php artisan make:model Flight -crR

# Згенерувати модель і клас FlightPolicy...
php artisan make:model Flight --policy

# Згенерувати модель і міграцію, фабрику, сідер та контролер...
php artisan make:model Flight -mfsc

# Скорочення для генерації моделі, міграції, фабрики, сідера, політики, контролера і form request...
php artisan make:model Flight --all
php artisan make:model Flight -a

# Згенерувати модель проміжної таблиці...
php artisan make:model Member --pivot
php artisan make:model Member -p

Огляд моделей

Іноді буває важко визначити всі доступні атрибути та звʼязки моделі, просто переглядаючи її код. Натомість спробуйте Artisan-команду model:show, яка надає зручний огляд усіх атрибутів і звʼязків моделі:

php artisan model:show Flight

Домовленості моделей Eloquent

Моделі, згенеровані командою make:model, розміщуються в теці app/Models. Розгляньмо базовий клас моделі й обговорімо деякі ключові домовленості Eloquent:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    // ...
}

Назви таблиць

Переглянувши приклад вище, ви могли помітити, що ми не вказали Eloquent, яка таблиця бази даних відповідає нашій моделі Flight. За домовленістю як назва таблиці використовується назва класу в «snake case» у множині, якщо явно не вказано іншу назву. Тож у цьому випадку Eloquent припустить, що модель Flight зберігає записи в таблиці flights, а модель AirTrafficController зберігатиме записи в таблиці air_traffic_controllers.

Якщо відповідна таблиця бази даних вашої моделі не відповідає цій домовленості, ви можете вручну вказати назву таблиці моделі за допомогою атрибута Table:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table('my_flights')]
class Flight extends Model
{
    // ...
}

Первинні ключі

Eloquent також припускає, що відповідна таблиця бази даних кожної моделі має колонку первинного ключа з назвою id. За потреби ви можете вказати іншу колонку, яка слугує первинним ключем моделі, за допомогою аргументу key атрибута Table:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table(key: 'flight_id')]
class Flight extends Model
{
    // ...
}

Крім того, Eloquent припускає, що первинний ключ є цілим числом, що автоінкрементується, а це означає, що Eloquent автоматично приведе первинний ключ до цілого числа. Якщо ви хочете використати первинний ключ без автоінкременту або нечисловий, вам слід вказати аргументи keyType та incrementing в атрибуті Table:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table(key: 'uuid', keyType: 'string', incrementing: false)]
class Flight extends Model
{
    // ...
}

Якщо вам потрібно лише вимкнути автоінкрементні ID, ви можете скористатися атрибутом WithoutIncrementing:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\WithoutIncrementing;
use Illuminate\Database\Eloquent\Model;

#[WithoutIncrementing]
class Flight extends Model
{
    // ...
}

«Складені» первинні ключі

Eloquent вимагає, щоб кожна модель мала принаймні один унікальний ідентифікатор «ID», який може слугувати її первинним ключем. «Складені» (composite) первинні ключі моделями Eloquent не підтримуються. Проте ви вільні додавати до своїх таблиць бази даних додаткові унікальні індекси з кількох колонок на додачу до унікального первинного ключа таблиці.

Ключі UUID та ULID

Замість цілих чисел з автоінкрементом як первинних ключів моделі Eloquent ви можете обрати UUID. UUID — це універсально унікальні буквено-цифрові ідентифікатори завдовжки 36 символів.

Якщо ви хочете, щоб модель використовувала ключ UUID замість автоінкрементного цілочислового ключа, ви можете використати трейт Illuminate\Database\Eloquent\Concerns\HasUuids на моделі. Звісно, вам слід переконатися, що модель має колонку первинного ключа, еквівалентну UUID:

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasUuids;

    // ...
}

$article = Article::create(['title' => 'Traveling to Europe']);

$article->id; // "018f2b5c-6a7f-7b12-9d6f-2f8a4e0c9c11"

За замовчуванням трейт HasUuids генеруватиме для ваших моделей ідентифікатори UUIDv7. Такі UUID ефективніші для індексованого зберігання в базі даних, бо їх можна сортувати лексикографічно.

Ви можете перевизначити процес генерації UUID для конкретної моделі, визначивши на моделі метод newUniqueId. Крім того, ви можете вказати, які колонки мають отримувати UUID, визначивши на моделі метод uniqueIds:

use Ramsey\Uuid\Uuid;

/**
 * Згенерувати новий UUID для моделі.
 */
public function newUniqueId(): string
{
    return (string) Uuid::uuid4();
}

/**
 * Отримати колонки, які мають отримувати унікальний ідентифікатор.
 *
 * @return array<int, string>
 */
public function uniqueIds(): array
{
    return ['id', 'discount_code'];
}

За бажання ви можете використовувати «ULID» замість UUID. ULID схожі на UUID, проте мають довжину лише 26 символів. Як і впорядковані UUID, ULID лексикографічно сортуються для ефективного індексування в базі даних. Щоб використовувати ULID, вам слід застосувати на моделі трейт Illuminate\Database\Eloquent\Concerns\HasUlids. Також вам слід переконатися, що модель має колонку первинного ключа, еквівалентну ULID:

use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    use HasUlids;

    // ...
}

$article = Article::create(['title' => 'Traveling to Asia']);

$article->id; // "01gd4d3tgrrfqeda94gdbtdk5c"

Часові мітки

За замовчуванням Eloquent очікує, що у відповідній таблиці бази даних вашої моделі існують колонки created_at та updated_at. Eloquent автоматично встановлюватиме значення цих колонок під час створення або оновлення моделей. Якщо ви не хочете, щоб ці колонки автоматично керувалися Eloquent, ви можете встановити timestamps у false в атрибуті Table вашої моделі:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table(timestamps: false)]
class Flight extends Model
{
    // ...
}

Якщо вам потрібно лише вимкнути часові мітки, ви можете скористатися атрибутом WithoutTimestamps:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\WithoutTimestamps;
use Illuminate\Database\Eloquent\Model;

#[WithoutTimestamps]
class Flight extends Model
{
    // ...
}

Якщо вам потрібно налаштувати формат часових міток вашої моделі, ви можете скористатися аргументом dateFormat атрибута Table. Він визначає, як атрибути дати зберігаються в базі даних, а також їхній формат під час серіалізації моделі в масив або JSON:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table(dateFormat: 'U')]
class Flight extends Model
{
    // ...
}

Якщо вам потрібно лише визначити формат дати, ви можете скористатися атрибутом DateFormat:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\DateFormat;
use Illuminate\Database\Eloquent\Model;

#[DateFormat('U')]
class Flight extends Model
{
    // ...
}

Якщо вам потрібно налаштувати назви колонок, які використовуються для зберігання часових міток, ви можете визначити на своїй моделі константи CREATED_AT та UPDATED_AT:

<?php

class Flight extends Model
{
    /**
     * Назва колонки "created at".
     *
     * @var string|null
     */
    public const CREATED_AT = 'creation_date';

    /**
     * Назва колонки "updated at".
     *
     * @var string|null
     */
    public const UPDATED_AT = 'updated_date';
}

Якщо ви хочете виконати операції над моделлю так, щоб часова мітка updated_at моделі не змінювалася, ви можете працювати з моделлю всередині замикання, переданого методу withoutTimestamps:

Model::withoutTimestamps(fn () => $post->increment('reads'));

Зʼєднання з базою даних

За замовчуванням усі моделі Eloquent використовуватимуть зʼєднання з базою даних, налаштоване для вашого застосунку за замовчуванням. Якщо ви хочете вказати інше зʼєднання, яке слід використовувати під час взаємодії з конкретною моделлю, ви можете скористатися атрибутом Connection:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Connection;
use Illuminate\Database\Eloquent\Model;

#[Connection('mysql')]
class Flight extends Model
{
    // ...
}

Значення атрибутів за замовчуванням

За замовчуванням щойно створений екземпляр моделі не міститиме жодних значень атрибутів. Якщо ви хочете визначити значення за замовчуванням для деяких атрибутів вашої моделі, ви можете визначити на моделі властивість $attributes. Значення атрибутів, розміщені в масиві $attributes, мають бути в сирому, «придатному для зберігання» форматі, наче їх щойно прочитали з бази даних:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * Значення атрибутів моделі за замовчуванням.
     *
     * @var array<string, mixed>
     */
    protected $attributes = [
        'options' => '[]',
        'delayed' => false,
    ];
}

Налаштування строгості Eloquent

Laravel пропонує кілька методів, які дозволяють налаштувати поведінку та «строгість» Eloquent у різних ситуаціях.

По-перше, метод preventLazyLoading приймає необовʼязковий булевий аргумент, який вказує, чи слід заборонити ліниве завантаження. Наприклад, ви можете захотіти вимкнути ліниве завантаження лише в непродакшн-середовищах, щоб ваше продакшн-середовище продовжувало працювати нормально, навіть якщо в продакшн-коді випадково опиниться ліниво завантажуваний звʼязок. Зазвичай цей метод слід викликати в методі boot AppServiceProvider вашого застосунку:

use Illuminate\Database\Eloquent\Model;

/**
 * Ініціалізація сервісів застосунку.
 */
public function boot(): void
{
    Model::preventLazyLoading(! $this->app->isProduction());
}

Крім того, ви можете вказати Laravel кидати виняток при спробі заповнити атрибут, недоступний для заповнення, викликавши метод preventSilentlyDiscardingAttributes. Це може допомогти запобігти несподіваним помилкам під час локальної розробки при спробі встановити атрибут, який не було додано до масиву fillable моделі:

Model::preventSilentlyDiscardingAttributes(! $this->app->isProduction());

Отримання моделей

Щойно ви створили модị та повʼязану з нею таблицю бази даних, ви готові починати отримувати дані з бази. Ви можете уявляти кожну модель Eloquent як потужний конструктор запитів (query builder), що дозволяє вам плавно робити запити до таблиці бази даних, повʼязаної з моделлю. Метод моделі all отримає всі записи з повʼязаної з моделлю таблиці бази даних:

use App\Models\Flight;

foreach (Flight::all() as $flight) {
    echo $flight->name;
}

Побудова запитів

Метод Eloquent all поверне всі результати з таблиці моделі. Проте, оскільки кожна модель Eloquent слугує конструктором запитів, ви можете додати до запитів додаткові обмеження, а потім викликати метод get, щоб отримати результати:

$flights = Flight::where('active', 1)
    ->orderBy('name')
    ->limit(10)
    ->get();

Примітка Оскільки моделі Eloquent є конструкторами запитів, вам варто переглянути всі методи, які надає конструктор запитів Laravel. Ви можете використовувати будь-який із цих методів під час написання запитів Eloquent.

Оновлення моделей

Якщо у вас уже є екземпляр моделі Eloquent, отриманий із бази даних, ви можете «оновити» модель за допомогою методів fresh та refresh. Метод fresh повторно отримає модель із бази даних. Наявний екземпляр моделі не буде змінено:

$flight = Flight::where('number', 'FR 900')->first();

$freshFlight = $flight->fresh();

Метод refresh наповнить наявну модель свіжими даними з бази даних. Крім того, буде оновлено й усі її завантажені звʼязки:

$flight = Flight::where('number', 'FR 900')->first();

$flight->number = 'FR 456';

$flight->refresh();

$flight->number; // "FR 900"

Якщо вам потрібно оновити модель і отримати песимістичне блокування в межах транзакції, ви можете скористатися методом refreshForUpdate. Цей метод перезавантажує модель, використовуючи блокування FOR UPDATE:

DB::transaction(function () use ($flight) {
    $flight->refreshForUpdate();

    // Оновити заблоковану модель...
});

Колекції

Як ми вже бачили, методи Eloquent на кшталт all та get отримують кілька записів із бази даних. Проте ці методи не повертають простий PHP-масив. Натомість повертається екземпляр Illuminate\Database\Eloquent\Collection.

Клас Eloquent Collection розширює базовий клас Laravel Illuminate\Support\Collection, який надає низку корисних методів для роботи з колекціями даних. Наприклад, метод reject можна використати для вилучення моделей із колекції на основі результатів викликаного замикання:

$flights = Flight::where('destination', 'Paris')->get();

$flights = $flights->reject(function (Flight $flight) {
    return $flight->cancelled;
});

Крім методів, які надає базовий клас колекції Laravel, клас колекції Eloquent надає кілька додаткових методів, призначених саме для роботи з колекціями моделей Eloquent.

Оскільки всі колекції Laravel реалізують ітеровані інтерфейси PHP, ви можете обходити колекції в циклі так, наче вони масиви:

foreach ($flights as $flight) {
    echo $flight->name;
}

Розбиття результатів на частини

Вашому застосунку може забракнути памʼяті, якщо ви спробуєте завантажити десятки тисяч записів Eloquent за допомогою методів all або get. Замість цих методів для ефективнішої обробки великої кількості моделей можна використати метод chunk.

Метод chunk отримає підмножину моделей Eloquent, передаючи їх у замикання для обробки. Оскільки за раз отримується лише поточна частина моделей Eloquent, метод chunk забезпечить значно менше споживання памʼяті під час роботи з великою кількістю моделей:

use App\Models\Flight;
use Illuminate\Database\Eloquent\Collection;

Flight::chunk(200, function (Collection $flights) {
    foreach ($flights as $flight) {
        // ...
    }
});

Перший аргумент, переданий методу chunk, — це кількість записів, які ви хочете отримувати за одну «частину». Замикання, передане другим аргументом, буде викликане для кожної частини, отриманої з бази даних. Для отримання кожної частини записів, переданої в замикання, буде виконано запит до бази даних.

Якщо ви фільтруєте результати методу chunk за колонкою, яку також оновлюватимете під час ітерації по результатах, вам слід використовувати метод chunkById. Використання методу chunk у таких сценаріях може призвести до неочікуваних і неузгоджених результатів. Усередині метод chunkById завжди отримуватиме моделі, у яких колонка id більша за значення в останній моделі попередньої частини:

Flight::where('departed', true)
    ->chunkById(200, function (Collection $flights) {
        $flights->each->update(['departed' => false]);
    }, column: 'id');

Оскільки методи chunkById та lazyById додають власні умови «where» до запиту, що виконується, вам зазвичай слід логічно групувати власні умови всередині замикання:

Flight::where(function ($query) {
    $query->where('delayed', true)->orWhere('cancelled', true);
})->chunkById(200, function (Collection $flights) {
    $flights->each->update([
        'departed' => false,
        'cancelled' => true
    ]);
}, column: 'id');

Розбиття на частини за допомогою лінивих колекцій

Метод lazy працює подібно до методу chunk у тому сенсі, що за лаштунками він виконує запит частинами. Проте замість передавання кожної частини безпосередньо в колбек як є, метод lazy повертає сплощену LazyCollection моделей Eloquent, що дозволяє вам працювати з результатами як з єдиним потоком:

use App\Models\Flight;

foreach (Flight::lazy() as $flight) {
    // ...
}

Якщо ви фільтруєте результати методу lazy за колонкою, яку також оновлюватимете під час ітерації по результатах, вам слід використовувати метод lazyById. Усередині метод lazyById завжди отримуватиме моделі, у яких колонка id більша за значення в останній моделі попередньої частини:

Flight::where('departed', true)
    ->lazyById(200, column: 'id')
    ->each->update(['departed' => false]);

Ви можете фільтрувати результати за спаданням id за допомогою методу lazyByIdDesc.

Курсори

Подібно до методу lazy, метод cursor можна використати, щоб значно зменшити споживання памʼяті вашим застосунком під час ітерації по десятках тисяч записів моделей Eloquent.

Метод cursor виконає лише один запит до бази даних; проте окремі моделі Eloquent не будуть наповнені даними, доки по них справді не пройде ітерація. Тому під час ітерації по курсору в памʼяті в будь-який момент часу зберігається лише одна модель Eloquent.

Увага Оскільки метод cursor тримає в памʼяті лише одну модель Eloquent за раз, він не може виконувати жадібне завантаження звʼязків. Якщо вам потрібне жадібне завантаження звʼязків, розгляньте натомість метод lazy.

Усередині метод cursor використовує генератори PHP для реалізації цієї функціональності:

use App\Models\Flight;

foreach (Flight::where('destination', 'Zurich')->cursor() as $flight) {
    // ...
}

cursor повертає екземпляр Illuminate\Support\LazyCollection. Ліниві колекції дозволяють вам використовувати багато методів колекцій, доступних у звичайних колекціях Laravel, завантажуючи при цьому в памʼять лише одну модель за раз:

use App\Models\User;

$users = User::cursor()->filter(function (User $user) {
    return $user->id > 500;
});

foreach ($users as $user) {
    echo $user->id;
}

Хоча метод cursor використовує значно менше памʼяті, ніж звичайний запит (тримаючи в памʼяті лише одну модель Eloquent за раз), памʼяті йому все одно зрештою забракне. Це через те, що PHP-драйвер PDO внутрішньо кешує всі сирі результати запиту у своєму буфері. Якщо ви маєте справу з дуже великою кількістю записів Eloquent, розгляньте натомість метод lazy.

Розширені підзапити

Підзапити в select

Eloquent також пропонує розширену підтримку підзапитів, яка дозволяє витягувати інформацію з повʼязаних таблиць одним запитом. Наприклад, уявімо, що ми маємо таблицю пунктів призначення рейсів destinations і таблицю рейсів flights до цих пунктів. Таблиця flights містить колонку arrived_at, яка вказує, коли рейс прибув до пункту призначення.

Використовуючи функціональність підзапитів, доступну в методах select та addSelect конструктора запитів, ми можемо вибрати всі destinations і назву рейсу, який останнім прибув до цього пункту призначення, одним запитом:

use App\Models\Destination;
use App\Models\Flight;

return Destination::addSelect(['last_flight' => Flight::select('name')
    ->whereColumn('destination_id', 'destinations.id')
    ->orderByDesc('arrived_at')
    ->limit(1)
])->get();

Сортування за підзапитом

Крім того, функція orderBy конструктора запитів підтримує підзапити. Продовжуючи наш приклад із рейсами, ми можемо використати цю можливість, щоб відсортувати всі пункти призначення за тим, коли до них прибув останній рейс. Знову ж таки, це можна зробити за один запит до бази даних:

return Destination::orderByDesc(
    Flight::select('arrived_at')
        ->whereColumn('destination_id', 'destinations.id')
        ->orderByDesc('arrived_at')
        ->limit(1)
)->get();

Отримання окремих моделей / агрегатів

Крім отримання всіх записів, що відповідають заданому запиту, ви також можете отримувати окремі записи за допомогою методів find, first або firstWhere. Замість колекції моделей ці методи повертають один екземпляр моделі:

use App\Models\Flight;

// Отримати модель за її первинним ключем...
$flight = Flight::find(1);

// Отримати першу модель, що відповідає обмеженням запиту...
$flight = Flight::where('active', 1)->first();

// Альтернатива для отримання першої моделі, що відповідає обмеженням запиту...
$flight = Flight::firstWhere('active', 1);

Іноді ви можете захотіти виконати якусь іншу дію, якщо результатів не знайдено. Методи findOr та firstOr повернуть один екземпляр моделі або, якщо результатів не знайдено, виконають задане замикання. Значення, повернуте замиканням, вважатиметься результатом методу:

$flight = Flight::findOr(1, function () {
    // ...
});

$flight = Flight::where('legs', '>', 3)->firstOr(function () {
    // ...
});

Винятки «не знайдено»

Іноді ви можете захотіти кинути виняток, якщо модель не знайдено. Це особливо корисно в маршрутах або контролерах. Методи findOrFail та firstOrFail отримають перший результат запиту; проте, якщо результату не знайдено, буде кинуто Illuminate\Database\Eloquent\ModelNotFoundException:

$flight = Flight::findOrFail(1);

$flight = Flight::where('legs', '>', 3)->firstOrFail();

Якщо ModelNotFoundException не перехоплено, клієнту автоматично надсилається HTTP-відповідь 404:

use App\Models\Flight;

Route::get('/api/flights/{id}', function (string $id) {
    return Flight::findOrFail($id);
});

Отримання або створення моделей

Метод firstOrCreate спробує знайти запис у базі даних за заданими парами колонка / значення. Якщо модель не вдається знайти в базі даних, буде вставлено запис з атрибутами, отриманими внаслідок обʼєднання першого масиву-аргументу з необовʼязковим другим масивом-аргументом.

Метод firstOrNew, як і firstOrCreate, спробує знайти в базі даних запис, що відповідає заданим атрибутам. Проте, якщо модель не знайдено, буде повернуто новий екземпляр моделі. Зверніть увагу, що модель, повернута firstOrNew, ще не збережена в базі даних. Вам потрібно буде вручну викликати метод save, щоб зберегти її:

use App\Models\Flight;

// Отримати рейс за назвою або створити його, якщо він не існує...
$flight = Flight::firstOrCreate([
    'name' => 'London to Paris'
]);

// Отримати рейс за назвою або створити його з атрибутами name, delayed та arrival_time...
$flight = Flight::firstOrCreate(
    ['name' => 'London to Paris'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

// Отримати рейс за назвою або створити новий екземпляр Flight...
$flight = Flight::firstOrNew([
    'name' => 'London to Paris'
]);

// Отримати рейс за назвою або створити екземпляр з атрибутами name, delayed та arrival_time...
$flight = Flight::firstOrNew(
    ['name' => 'Tokyo to Sydney'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

Отримання агрегатів

Працюючи з моделями Eloquent, ви також можете використовувати методи count, sum, max та інші агрегатні методи, які надає конструктор запитів Laravel. Як і слід очікувати, ці методи повертають скалярне значення замість екземпляра моделі Eloquent:

$count = Flight::where('active', 1)->count();

$max = Flight::where('active', 1)->max('price');

Вставка та оновлення моделей

Вставка

Звісно, використовуючи Eloquent, нам потрібно не лише отримувати моделі з бази даних. Нам також потрібно вставляти нові записи. На щастя, Eloquent робить це просто. Щоб вставити новий запис у базу даних, вам слід створити новий екземпляр моделі й встановити на ній атрибути. Потім викличте метод save на екземплярі моделі:

<?php

namespace App\Http\Controllers;

use App\Models\Flight;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * Зберегти новий рейс у базі даних.
     */
    public function store(Request $request): RedirectResponse
    {
        // Валідація запиту...

        $flight = new Flight;

        $flight->name = $request->name;

        $flight->save();

        return redirect('/flights');
    }
}

У цьому прикладі ми присвоюємо поле name з вхідного HTTP-запиту атрибуту name екземпляра моделі App\Models\Flight. Коли ми викликаємо метод save, у базу даних буде вставлено запис. Часові мітки моделі created_at та updated_at буде автоматично встановлено під час виклику методу save, тож немає потреби встановлювати їх вручну.

Якщо ви хочете зберегти модель у межах транзакції бази даних, ви можете скористатися методом saveOrFail. Якщо під час збереження буде кинуто виняток, транзакцію буде автоматично відкочено:

$flight->saveOrFail();

Як альтернативу ви можете використати метод create, щоб «зберегти» нову модель однією PHP-інструкцією. Вставлений екземпляр моделі буде повернуто вам методом create:

use App\Models\Flight;

$flight = Flight::create([
    'name' => 'London to Paris',
]);

Проте, перш ніж використовувати метод create, вам потрібно буде вказати на класі моделі атрибут Fillable або Guarded. Ці атрибути обовʼязкові, оскільки всі моделі Eloquent за замовчуванням захищені від вразливостей масового присвоєння (mass assignment). Щоб дізнатися більше про масове присвоєння, зверніться до документації з масового присвоєння.

Оновлення

Метод save також можна використовувати для оновлення моделей, які вже існують у базі даних. Щоб оновити модель, вам слід отримати її й встановити будь-які атрибути, які ви хочете оновити. Потім вам слід викликати метод save моделі. Знову ж таки, часову мітку updated_at буде оновлено автоматично, тож немає потреби встановлювати її значення вручну:

use App\Models\Flight;

$flight = Flight::find(1);

$flight->name = 'Paris to London';

$flight->save();

Якщо ви хочете оновити модель у межах транзакції бази даних, ви можете скористатися методом updateOrFail. Якщо під час оновлення буде кинуто виняток, транзакцію буде автоматично відкочено:

$flight->updateOrFail(['name' => 'Paris to London']);

Іноді вам може знадобитися оновити наявну модель або створити нову, якщо відповідної моделі не існує. Як і метод firstOrCreate, метод updateOrCreate зберігає модель, тож немає потреби вручну викликати метод save.

У прикладі нижче, якщо існує рейс із місцем відправлення departure Oakland та пунктом призначення destination San Diego, його колонки price та discounted буде оновлено. Якщо такого рейсу не існує, буде створено новий рейс з атрибутами, отриманими внаслідок обʼєднання першого масиву-аргументу з другим:

$flight = Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99, 'discounted' => 1]
);

Використовуючи методи на кшталт firstOrCreate чи updateOrCreate, ви можете не знати, чи було створено нову модель, чи оновлено наявну. Властивість wasRecentlyCreated вказує, чи було модель створено протягом її поточного життєвого циклу:

$flight = Flight::updateOrCreate(
    // ...
);

if ($flight->wasRecentlyCreated) {
    // Було вставлено новий запис рейсу...
}

Масові оновлення

Оновлення також можна виконувати над моделями, що відповідають заданому запиту. У цьому прикладі всі рейси, які є active і мають destination San Diego, буде позначено як затримані:

Flight::where('active', 1)
    ->where('destination', 'San Diego')
    ->update(['delayed' => 1]);

Метод update очікує масив пар колонка-значення, що представляють колонки, які слід оновити. Метод update повертає кількість зачеплених рядків.

Увага Під час виконання масового оновлення через Eloquent події моделі saving, saved, updating та updated не спрацьовуватимуть для оновлених моделей. Це тому, що під час масового оновлення моделі насправді ніколи не отримуються.

Дослідження змін атрибутів

Eloquent надає методи isDirty, isClean та wasChanged, щоб досліджувати внутрішній стан вашої моделі й визначати, як змінилися її атрибути з моменту, коли модель було спочатку отримано.

Метод isDirty визначає, чи змінився будь-який з атрибутів моделі з моменту її отримання. Ви можете передати методу isDirty конкретну назву атрибута або масив атрибутів, щоб визначити, чи є якісь із них «брудними». Метод isClean визначить, чи атрибут залишився незмінним з моменту отримання моделі. Цей метод також приймає необовʼязковий аргумент-атрибут:

use App\Models\User;

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
$user->isDirty(['first_name', 'title']); // true

$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true
$user->isClean(['first_name', 'title']); // false

$user->save();

$user->isDirty(); // false
$user->isClean(); // true

Метод wasChanged визначає, чи були змінені якісь атрибути під час останнього збереження моделі в поточному циклі запиту. За потреби ви можете передати назву атрибута, щоб побачити, чи було змінено конкретний атрибут:

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->save();

$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged(['title', 'slug']); // true
$user->wasChanged('first_name'); // false
$user->wasChanged(['first_name', 'title']); // true

Метод getOriginal повертає масив, що містить оригінальні атрибути моделі, незалежно від будь-яких змін у моделі з моменту її отримання. За потреби ви можете передати конкретну назву атрибута, щоб отримати оригінальне значення певного атрибута:

$user = User::find(1);

$user->name; // John
$user->email; // [email protected]

$user->name = 'Jack';
$user->name; // Jack

$user->getOriginal('name'); // John
$user->getOriginal(); // Масив оригінальних атрибутів...

Метод getChanges повертає масив, що містить атрибути, які змінилися під час останнього збереження моделі, а метод getPrevious повертає масив, що містить оригінальні значення атрибутів до останнього збереження моделі:

$user = User::find(1);

$user->name; // John
$user->email; // [email protected]

$user->update([
    'name' => 'Jack',
    'email' => '[email protected]',
]);

$user->getChanges();

/*
    [
        'name' => 'Jack',
        'email' => '[email protected]',
    ]
*/

$user->getPrevious();

/*
    [
        'name' => 'John',
        'email' => '[email protected]',
    ]
*/

Масове присвоєння

Ви можете використати метод create, щоб «зберегти» нову модель однією PHP-інструкцією. Вставлений екземпляр моделі буде повернуто вам цим методом:

use App\Models\Flight;

$flight = Flight::create([
    'name' => 'London to Paris',
]);

Проте, перш ніж використовувати метод create, вам потрібно буде вказати на класі моделі атрибут Fillable або Guarded. Ці атрибути обовʼязкові, оскільки всі моделі Eloquent за замовчуванням захищені від вразливостей масового присвоєння.

Вразливість масового присвоєння виникає, коли користувач передає неочікуване поле HTTP-запиту, і це поле змінює колонку у вашій базі даних, яку ви не очікували змінити. Наприклад, зловмисник може надіслати параметр is_admin через HTTP-запит, який потім передається в метод create вашої моделі, дозволяючи користувачеві підвищити себе до адміністратора.

Отже, для початку вам слід визначити, які атрибути моделі ви хочете зробити доступними для масового присвоєння. Це можна зробити за допомогою атрибута Fillable на моделі. Наприклад, зробімо атрибут name нашої моделі Flight доступним для масового присвоєння:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;

#[Fillable(['name'])]
class Flight extends Model
{
    // ...
}

Щойно ви вказали, які атрибути доступні для масового присвоєння, ви можете використати метод create, щоб вставити новий запис у базу даних. Метод create повертає щойно створений екземпляр моделі:

$flight = Flight::create(['name' => 'London to Paris']);

Якщо у вас уже є екземпляр моделі, ви можете використати метод fill, щоб наповнити його масивом атрибутів:

$flight->fill(['name' => 'Amsterdam to Frankfurt']);

Масове присвоєння та колонки JSON

Присвоюючи колонки JSON, кожен ключ колонки, доступний для масового присвоєння, має бути вказаний в атрибуті Fillable вашої моделі. З міркувань безпеки Laravel не підтримує оновлення вкладених атрибутів JSON при використанні атрибута Guarded:

use Illuminate\Database\Eloquent\Attributes\Fillable;

#[Fillable(['options->enabled'])]
class Flight extends Model
{
    // ...
}

Дозвіл масового присвоєння

Якщо ви хочете зробити всі свої атрибути доступними для масового присвоєння, ви можете використати атрибут Unguarded на своїй моделі. Якщо ви вирішите зняти захист із моделі, вам слід особливо подбати про те, щоб завжди формувати масиви, які передаються в методи Eloquent fill, create та update, вручну:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Unguarded;
use Illuminate\Database\Eloquent\Model;

#[Unguarded]
class Flight extends Model
{
    // ...
}

Винятки масового присвоєння

За замовчуванням атрибути, не включені в атрибут Fillable, мовчки відкидаються під час виконання операцій масового присвоєння. У продакшні це очікувана поведінка; проте під час локальної розробки це може призводити до плутанини, чому зміни моделі не набувають чинності.

За бажання ви можете вказати Laravel кидати виняток при спробі заповнити атрибут, недоступний для заповнення, викликавши метод preventSilentlyDiscardingAttributes. Зазвичай цей метод слід викликати в методі boot класу AppServiceProvider вашого застосунку:

use Illuminate\Database\Eloquent\Model;

/**
 * Ініціалізація сервісів застосунку.
 */
public function boot(): void
{
    Model::preventSilentlyDiscardingAttributes($this->app->isLocal());
}

Upsert-операції

Метод Eloquent upsert можна використати для оновлення або створення записів однією атомарною операцією. Перший аргумент методу складається зі значень для вставки або оновлення, а другий аргумент перелічує колонки, які унікально ідентифікують записи у відповідній таблиці. Третій і останній аргумент методу — це масив колонок, які слід оновити, якщо відповідний запис уже існує в базі даних. Метод upsert автоматично встановить часові мітки created_at та updated_at, якщо часові мітки увімкнені на моделі:

Flight::upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], uniqueBy: ['departure', 'destination'], update: ['price']);

Увага Усі бази даних, окрім SQL Server, вимагають, щоб колонки в другому аргументі методу upsert мали «первинний» (primary) або «унікальний» (unique) індекс. Крім того, драйвери баз даних MariaDB та MySQL ігнорують другий аргумент методу upsert і завжди використовують «первинні» та «унікальні» індекси таблиці для виявлення наявних записів.

Видалення моделей

Щоб видалити модель, ви можете викликати метод delete на екземплярі моделі:

use App\Models\Flight;

$flight = Flight::find(1);

$flight->delete();

Якщо ви хочете видалити модель у межах транзакції бази даних, ви можете скористатися методом deleteOrFail. Якщо під час видалення буде кинуто виняток, транзакцію буде автоматично відкочено:

$flight->deleteOrFail();

Видалення наявної моделі за її первинним ключем

У прикладі вище ми отримуємо модель із бази даних перед викликом методу delete. Проте, якщо ви знаєте первинний ключ моделі, ви можете видалити модель, не отримуючи її явно, викликавши метод destroy. Крім одного первинного ключа, метод destroy прийме кілька первинних ключів, масив первинних ключів або колекцію первинних ключів:

Flight::destroy(1);

Flight::destroy(1, 2, 3);

Flight::destroy([1, 2, 3]);

Flight::destroy(collect([1, 2, 3]));

Якщо ви використовуєте мʼяке видалення моделей, ви можете остаточно видалити моделі за допомогою методу forceDestroy:

Flight::forceDestroy(1);

Увага Метод destroy завантажує кожну модель окремо й викликає метод delete, щоб події deleting та deleted належно відправлялися для кожної моделі.

Видалення моделей за допомогою запитів

Звісно, ви можете побудувати запит Eloquent, щоб видалити всі моделі, які відповідають критеріям вашого запиту. У цьому прикладі ми видалимо всі рейси, позначені як неактивні. Як і масові оновлення, масові видалення не відправлятимуть події моделі для видалених моделей:

$deleted = Flight::where('active', 0)->delete();

Щоб видалити всі моделі в таблиці, вам слід виконати запит без додавання жодних умов:

$deleted = Flight::query()->delete();

Увага Під час виконання інструкції масового видалення через Eloquent події моделі deleting та deleted не відправлятимуться для видалених моделей. Це тому, що під час виконання інструкції видалення моделі насправді ніколи не отримуються.

Мʼяке видалення

Крім фактичного вилучення записів із вашої бази даних, Eloquent також може «мʼяко видаляти» (soft delete) моделі. Коли моделі мʼяко видалено, вони насправді не вилучаються з вашої бази даних. Натомість на моделі встановлюється атрибут deleted_at, який вказує дату й час, коли модель було «видалено». Щоб увімкнути мʼяке видалення для моделі, додайте до моделі трейт Illuminate\Database\Eloquent\SoftDeletes:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Flight extends Model
{
    use SoftDeletes;
}

Примітка Трейт SoftDeletes автоматично приведе атрибут deleted_at до екземпляра DateTime / Carbon за вас.

Вам також слід додати колонку deleted_at до вашої таблиці бази даних. Конструктор схеми Laravel містить допоміжний метод для створення цієї колонки:

Не перекладено підрозділи: Querying Soft Deleted Models, Pruning Models, Replicating Models, Query Scopes (Global Scopes, Local Scopes, Pending Attributes), Comparing Models, Events (Using Closures, Observers, Muting Events).

ЯК ЦЯ СТОРІНКА ВИГЛЯДАЄ В ПОШУКУ
phpukraine.com/docs/laravel/eloquent
Початок роботи — Laravel документація українською
Початок роботи у Laravel 13.x: переклад офіційної документації українською. Оновлено 4 вересня 2026. Приклади коду, пояснення та посилання на питання зі співбесід.
Переклад робить спільнота

Виправити терміни, дописати розділ або взяти нову главу може кожен. Термінологію узгоджуємо в глосарії, щоб переклад лишався однорідним.

1
Перекладачів
90%
Готовності
0
Вільних розділів
Глосарій термінів