Introduction
Eloquent is Laravel's ActiveRecord ORM. Every database table gets a corresponding PHP model class, and Eloquent handles inserts, updates, queries, and relationships through a fluent, readable API.
Key Concepts
- ORM (Object-Relational Mapper): A library that maps database tables to classes and rows to instances.
- ActiveRecord: A design pattern where the model class both represents data and provides methods to persist it (
$user->save()). - Model: A PHP class extending
Illuminate\Database\Eloquent\Modelthat represents one database table. - Convention: Eloquent's defaults — singular class names, plural snake_case table names,
idprimary keys,created_at/updated_attimestamps. - Query Builder: Laravel's lower-level SQL builder that Eloquent is built on.
Real World Context
Eloquent is how 99% of Laravel applications talk to their database. Raw PDO is rare. Understanding Eloquent's ActiveRecord mental model is the baseline for every data-driven feature you'll build — from a simple CRUD admin to a multi-tenant SaaS.
Deep Dive
Eloquent is Laravel's Object-Relational Mapper (ORM). It provides a beautiful, simple ActiveRecord implementation for working with your database, where each database table has a corresponding "Model" class.
What is an ORM?
An ORM maps:
- PHP classes → Database tables
- Class properties → Table columns
- Class instances → Table rows
PHP Class: User Database Table: users
┌─────────────────────────┐ ┌────┬───────────┬─────────────────┐
│ class User extends Model │ │ id │ name │ email │
│ { │ ├────┼───────────┼─────────────────┤
│ // Properties mapped │ ───► │ 1 │ "John" │ "john@mail.com" │
│ // automatically │ │ 2 │ "Jane" │ "jane@mail.com" │
│ } │ └────┴───────────┴─────────────────┘
└─────────────────────────┘
Why Use Eloquent?
Traditional SQL Approach
php// Without ORM - raw PDO/SQL $pdo = new PDO('mysql:host=localhost;dbname=app', 'root', 'password'); $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([1]); $user = $stmt->fetch(PDO::FETCH_ASSOC); $name = $user['name'];
Eloquent Approach
php// With Eloquent - elegant and simple $user = User::find(1); $name = $user->name;
Benefits of Eloquent
| Feature | Benefit |
|---|---|
| Expressive Syntax | Write readable, intuitive database code |
| Relationships | Define related data with simple methods |
| Mass Assignment | Securely create/update multiple fields |
| Soft Deletes | "Delete" records without removing data |
| Events & Observers | Hook into model lifecycle events |
| Query Scopes | Reusable query constraints |
| Mutators & Casts | Transform data automatically |
| Serialization | Easy JSON/array conversion |
Your First Model
A simple Eloquent model:
php<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { // That's it! Eloquent handles everything else. }
With this simple class, you can:
php// Create $post = Post::create(['title' => 'Hello World', 'body' => '...']); // Read $post = Post::find(1); $posts = Post::all(); $posts = Post::where('published', true)->get(); // Update $post->title = 'Updated Title'; $post->save(); // Delete $post->delete();
Eloquent Conventions
Eloquent uses sensible defaults based on conventions:
Table Names
phpclass User extends Model {} // Table: users class Post extends Model {} // Table: posts class Category extends Model {} // Table: categories (pluralized) class Person extends Model {} // Table: people (irregular plural)
Primary Keys
php// Default: id column, auto-incrementing integer $user = User::find(1); // Finds by 'id' column
Timestamps
php// Default: created_at and updated_at columns // Automatically managed by Eloquent $post->created_at; // Carbon instance $post->updated_at; // Carbon instance
The Models Directory
Models live in app/Models/:
app/Models/
├── User.php # User model
├── Post.php # Post model
├── Comment.php # Comment model
└── Category.php # Category model
Model vs Query Builder
Eloquent is built on top of Laravel's Query Builder:
php// Query Builder - returns stdClass objects DB::table('users')->where('active', true)->get(); // Eloquent - returns User model instances User::where('active', true)->get();
Eloquent models have additional features like:
- Relationships
- Events/observers
- Accessors/mutators
- Serialization options
Common Pitfalls
- Treating models as DTOs — Models carry persistence logic; pure data transfer should use dedicated classes (Data objects, Spatie Data, etc.).
- Ignoring mass assignment protection —
User::create($request->all())without$fillablelets attackers set any column. - Mixing Query Builder and Eloquent APIs unnecessarily — Stick with Eloquent unless you genuinely need the Query Builder's lower-level access.
Best Practices
- One model per table — Keep the mapping simple; save fancy patterns for when you need them.
- Enable strict mode in development —
Model::preventLazyLoading(),preventSilentlyDiscardingAttributes(),preventAccessingMissingAttributes()catch bugs early. - Let conventions guide your schema — Pluralize table names, use
idPKs, let Eloquent infer the rest.
Summary
- Eloquent maps classes to tables, properties to columns, instances to rows.
- Every model extends
Illuminate\Database\Eloquent\Model. - Conventions handle table names, primary keys, and timestamps automatically.
- Eloquent is built on Laravel's Query Builder and inherits every where/join/aggregate helper.
- Strict mode helpers catch lazy loading and missing attributes in development.