Введение в Eloquent ORM
Что такое ORM
ORM (Object-Relational Mapping) — это прослойка между кодом на PHP и базой данных. Вместо того чтобы писать SQL-запросы вручную, ты работаешь с объектами: каждая таблица — класс, каждая строка — экземпляр.
Без ORM:
$pdo = new PDO('pgsql:host=localhost;dbname=app', 'user', 'pass');
$stmt = $pdo->prepare('SELECT * FROM posts WHERE id = ?');
$stmt->execute([1]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['title'];
С Eloquent:
$post = Post::find(1);
echo $post->title;
Разница: во втором случае ты не думаешь про SQL, соединение, экранирование, типы.
Что даёт Eloquent
- Типизация — IDE подсказывает свойства и методы.
- Защита от SQL-инъекций — параметры биндятся автоматически.
- Связи —
$user->postsвместо JOIN. - Аксессоры и мутаторы — преобразование данных.
- События —
creating,updated. - Soft Deletes — «мягкое» удаление.
- Скоупы — переиспользуемые условия.
- Жадная загрузка — решение N+1.
Место Eloquent в Laravel
Laravel использует Active Record:
- Модель = строка БД + методы.
$post->save()— модель сама себя сохраняет.$post->delete()— сама удаляет.
Альтернатива — Data Mapper (Doctrine):
- Модель не знает о БД.
- Отдельный EntityManager сохраняет.
- Больше кода, но чище архитектура.
Eloquent — Active Record. Просто, быстро, идиоматично для Laravel.
Соглашение об именах
Правило: модель — единственное число, таблица — множественное.
| Модель | Таблица |
|---|---|
User | users |
Post | posts |
Article | articles |
Category | categories |
Person | people |
Если таблица называется иначе:
protected $table = 'my_posts';
Модель
Создание:
php artisan make:model Post
Файл app/Models/Post.php:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
//
}
Основные концепции
Модель — класс, привязанный к таблице.
Атрибуты — свойства модели:
$post->title; // читать
$post->title = 'X'; // писать
Связи — методы, описывающие отношения:
public function user()
{
return $this->belongsTo(User::class);
}
Скоупы — переиспользуемые условия:
public function scopePublished($query)
{
return $query->where('published', true);
}
Аксессоры и мутаторы — преобразование значений:
protected function title(): Attribute
{
return Attribute::make(
get: fn ($value) => ucfirst($value),
);
}
Что можно с Eloquent
Полный CRUD:
Post::create(['title' => 'X']); // создать
Post::find(1); // прочитать
$post->update(['title' => 'Y']); // обновить
$post->delete(); // удалить
Сложные запросы:
Post::where('status', 'published')
->where('views', '>', 100)
->orderBy('created_at', 'desc')
->limit(10)
->get();
Связи:
$user->posts; // все посты пользователя
$post->user; // автор поста
$post->tags; // теги поста
Агрегаты:
Post::count();
Post::max('views');
Post::avg('rating');
Что не стоит делать
Тяжёлые отчёты — лучше Query Builder или чистый SQL:
// Eloquent умеет, но медленнее
Post::with('user', 'comments', 'tags')->get();
// Query Builder быстрее
DB::table('posts')
->join('users', 'posts.user_id', '=', 'users.id')
->select('posts.id', 'posts.title', 'users.name')
->get();
Массовые операции — Eloquent строит объекты, это медленно:
// Плохо: создаст 100 000 объектов
Post::all()->each(fn ($p) => $p->update(['status' => 'x']));
// Хорошо: один UPDATE
Post::query()->update(['status' => 'x']);
Что дальше
- Модели и конвенции
- CRUD: создание и чтение
- Массовые операции и upsert
- Soft Deletes
- Скоупы
- Связи: один-к-одному, один-ко-многим
- Связи: многие-ко-многим
- Полиморфные связи
- Жадная загрузка и N+1
- Выборка данных: select, get, where, orderBy, пагинация
- Аксессоры, мутаторы и сериализация
- Продвинутые техники и паттерны
Итог
- Eloquent — ORM поверх Laravel.
- Active Record: модель знает о БД.
- Таблица = модель во множественном числе.
- CRUD — через методы модели.
- Связи, скоупы, события — из коробки.
- Для отчётов — Query Builder или SQL.
Дальше — модели и конвенции.