Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти
Інше
Події Про нас

Junior: питання на співбесіді з теми «Eloquent»

Найпопулярніші питання з реальних Laravel/PHP співбесід для всіх рівнів

7 питань

Eloquent - це ORM (object-relational mapping) Laravel, реалізація патерну Active Record. Кожній таблиці відповідає модель (зазвичай у app/Models), рядок таблиці - це екземпляр моделі, а робота з даними виглядає як робота зі звичайними PHP-об'єктами замість написання SQL.

Створити модель (за конвенцією однина: Post → таблиця posts):

php artisan make:model Post -mf   # одразу з міграцією та фабрикою

Базові операції (CRUD):

$post = Post::create(['title' => 'Привіт']); // create
$post = Post::find(1);                       // read
$post->update(['title' => 'Оновлено']);      // update
$post->delete();                             // delete

Post::where('is_published', true)->latest()->get();

Що дає Eloquent понад Query Builder:

  • Зв'язки - hasOne, hasMany, belongsTo, belongsToMany, поліморфні.
  • Аксесори/мутатори та касти атрибутів (наприклад, дати, enum, JSON).
  • Події моделі та обзервери (creating, saved, deleted).
  • Scopes для перевикористання умов запитів.

Eloquent побудований поверх Query Builder, тож ті самі методи (where, orderBy, join) доступні і на моделях.

Докладніше в документації: Eloquent ORM

Обидва методи виконують запит, але повертають різне:

  • get() повертає колекцію (Illuminate\Database\Eloquent\Collection) усіх відповідних моделей. Якщо нічого не знайдено - порожню колекцію, а не null. Підходить, коли треба перебрати кілька записів.
  • first() повертає одну першу модель або null, якщо нічого не знайдено. Підходить, коли очікуєш один запис.
$posts = Post::where('active', true)->get();   // Collection (0..N моделей)
$post  = Post::where('slug', $slug)->first();  // Post|null

foreach ($posts as $post) { /* ... */ }        // get() - ітеруємо
echo $post?->title;                            // first() - перевіряємо на null

Споріднені методи:

  • find($id) - пошук за первинним ключем.
  • firstOrFail() / findOrFail() - як first()/find(), але кидають ModelNotFoundException (HTTP 404), якщо запис відсутній.
  • pluck('email') - колекція значень одного стовпця.
  • value('email') - одне скалярне значення з першого рядка.

Підсумок: get() - багато рядків (колекція), first() - один рядок (модель або null).

Докладніше в документації: Eloquent: отримання моделей

Eloquent підтримує всі поширені типи зв'язків між таблицями, кожен оголошується методом на моделі:

  • One To One - hasOne / belongsTo. Приклад: UserProfile.
  • One To Many - hasMany / belongsTo. Приклад: Post → багато Comment.
  • Many To Many - belongsToMany через проміжну (pivot) таблицю. Приклад: UserRole.
  • Has One/Many Through - доступ до віддаленого зв'язку через проміжну модель.
  • Polymorphic - morphTo / morphMany: модель належить кільком типам (наприклад, Comment може належати і Post, і Video).

Оголошення зв'язку:

class Post extends Model
{
    public function comments(): HasMany
    {
        return $this->hasMany(Comment::class);
    }
}

class Comment extends Model
{
    public function post(): BelongsTo
    {
        return $this->belongsTo(Post::class);
    }
}

Використання:

$post->comments;               // колекція коментарів
$comment->post->title;         // зворотний бік
Post::with('comments')->get(); // eager loading проти N+1

Завжди завантажуйте потрібні зв'язки через with(), щоб уникнути проблеми N+1.

Докладніше в документації: Зв’язки Eloquent

Soft Deletes - «м'яке» видалення: запис не стирається фізично, а отримує мітку часу в колонці deleted_at. Такі записи автоматично виключаються з усіх запитів.

class Post extends Model
{
    use SoftDeletes; // + $table->softDeletes() у міграції
}

$post->delete(); // ставить deleted_at
Post::withTrashed()->get(); // включно з видаленими
$post->restore(); // відновити
$post->forceDelete(); // видалити назавжди

Навіщо: можливість відновлення, аудит, збереження посилальної цілісності.

Докладніше в документації: Soft Deletes

Вони перетворюють атрибути моделі «на льоту». У сучасному Laravel обидва описуються одним методом, що повертає Attribute:

protected function name(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value), // accessor (читання)
        set: fn (string $value) => strtolower($value), // mutator (запис)
    );
}
  • Accessor форматує значення при отриманні ($user->name).
  • Mutator форматує значення перед збереженням у БД.

Корисно для форматування, нормалізації або роботи з Value Objects.

Докладніше в документації: Accessors та Mutators

  • find($id) повертає модель за первинним ключем або null.
  • findOrFail($id) повертає модель або кидає ModelNotFoundException, яку Laravel автоматично перетворює на HTTP 404.
$post = Post::find($id);
if (! $post) { abort(404); } // ручна перевірка

$post = Post::findOrFail($id); // те саме одним рядком

findOrFail робить контролери чистішими. Аналогічна пара для запитів - first() / firstOrFail().

Докладніше в документації: Eloquent: не знайдено / findOrFail

Це «upsert»-методи, що позбавляють від ручних перевірок «існує / не існує».

// знайти за email; якщо нема - створити з усіма атрибутами
User::firstOrCreate(
    ['email' => $email],
    ['name' => $name]
);

// знайти за email; оновити name; якщо нема - створити
User::updateOrCreate(
    ['email' => $email],
    ['name' => $name]
);

Перший масив - умови пошуку, другий - значення для створення/оновлення. Споріднений firstOrNew() повертає незбережений екземпляр.

Докладніше в документації: Eloquent: upsert-методи