Eloquent ORM
Object-Relational Mapping in Laravel
Eloquent ORM is a powerful and simple ORM for working with database in Laravel. This ORM uses Active Record pattern and allows you to work with database tables in an object-oriented way.
Main Eloquent Features:
- <strong>Active Record Pattern</strong>: Each Model represents a row in database table
- <strong>Relationships</strong>: Defining relationships between models simply
- <strong>Query Builder</strong>: Using fluent query builder for complex queries
- <strong>Mass Assignment Protection</strong>: Protection against mass assignment vulnerabilities
- <strong>Accessors & Mutators</strong>: Transforming data when reading and writing
- <strong>Events</strong>: Lifecycle events for hooks
- <strong>Scopes</strong>: Query scopes for reusable queries
- <strong>Soft Deletes</strong>: Soft deletion without actually deleting from database
- <strong>Timestamps</strong>: Automatic management of created_at and updated_at
- <strong>Casting</strong>: Automatic type conversion
- <strong>Pagination</strong>: Built-in pagination
- <strong>Eager Loading</strong>: Preventing N+1 query problem
Benefits of Eloquent:
- Clean and readable code
- Better security with mass assignment protection
- Easy work with relationships
- Type safety with casting
- Performance optimization with eager loading
- Better developer experience
Examples
Creating Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'users';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
protected $casts = [
'email_verified_at' => 'datetime',
'is_active' => 'boolean'
];
}
A simple Model that defines table and fillable fields.
CRUD Operations
// Create
$user = User::create([
'name' => 'John Doe',
'email' => 'john@example.com'
]);
// Read
$user = User::find(1);
$users = User::all();
$user = User::where('email', 'john@example.com')->first();
// Update
$user->name = 'Jane Doe';
$user->save();
// Or
$user->update(['name' => 'Jane Doe']);
// Delete
$user->delete();
// Or
User::destroy(1);
CRUD operations with Eloquent.
Query Builder Integration
// Eloquent uses Query Builder
$users = User::where('active', true)
->where('age', '>', 18)
->orderBy('name')
->limit(10)
->get();
// Aggregates
$count = User::where('active', true)->count();
$maxAge = User::max('age');
$avgAge = User::avg('age');
// Chaining
$users = User::query()
->where('active', true)
->orWhere('verified', true)
->get();
Using Query Builder with Eloquent.
Mass Assignment
// Fillable (allowed)
class User extends Model
{
protected $fillable = ['name', 'email'];
}
// Guarded (blocked)
class User extends Model
{
protected $guarded = ['id', 'is_admin'];
}
// Usage
User::create(['name' => 'John', 'email' => 'john@example.com']);
// Force fill (bypass protection)
$user->forceFill(['is_admin' => true]);
Mass assignment protection with fillable and guarded.
Timestamps
// Automatic timestamps
class User extends Model
{
// created_at and updated_at are managed automatically
}
// Disable timestamps
class User extends Model
{
public $timestamps = false;
}
// Custom timestamp names
class User extends Model
{
const CREATED_AT = 'created_date';
const UPDATED_AT = 'modified_date';
}
// Touch parent timestamps
$post->user->touch();
Managing timestamps in Eloquent.
Model Events
<?php
class User extends Model
{
protected static function booted()
{
static::creating(function ($user) {
// Before create
});
static::created(function ($user) {
// After create
});
static::updating(function ($user) {
// Before update
});
static::deleting(function ($user) {
// Before delete
});
}
}
Model events for lifecycle hooks.
Pagination
// Simple pagination
$users = User::paginate(15);
// With query string
$users = User::paginate(15)->withQueryString();
// Cursor pagination (for large datasets)
$users = User::cursorPaginate(15);
// Simple pagination (prev/next only)
$users = User::simplePaginate(15);
// In view
{{ $users->links() }}
// Custom pagination view
{{ $users->links('custom.pagination') }}
Pagination with Eloquent.
Chunking
// Process large datasets in chunks
User::chunk(100, function ($users) {
foreach ($users as $user) {
// Process user
}
});
// Chunk by ID (more efficient)
User::chunkById(100, function ($users) {
foreach ($users as $user) {
// Process user
}
});
// Lazy loading (memory efficient)
foreach (User::lazy() as $user) {
// Process user
}
Chunking for processing large datasets.
Use Cases
- Creating and managing database records
- Defining relationships between models
- Query building with fluent interface
- Data transformation with accessors/mutators
- Event handling for business logic
- Pagination and chunking for large datasets
Common Mistakes
- N+1 query problem with relationships
- Not using eager loading
- Mass assignment vulnerabilities
- Using all() for large datasets
- Forgetting indexes for foreign keys
- Not using transactions for multiple operations
Best Practices
- Use eager loading for relationships
- Use fillable or guarded for mass assignment protection
- Use indexes for foreign keys
- Use transactions for multiple operations
- Use chunking for large datasets
- Use scopes for reusable queries
- Use model events for business logic
Edge Cases
- Very large datasets requiring chunking
- Complex relationships with multiple levels
- Polymorphic relationships
- Model events with circular dependencies
- Mass assignment with nested data
- Timestamps in different timezones
Performance Notes
- Eager loading can solve N+1 problem
- Indexes for foreign keys are important
- Chunking for large datasets is essential
- Query caching can improve performance
- Using select() for specific columns
- Lazy loading can save memory
Security Notes
- Always use fillable or guarded
- Use forceFill() only for trusted data
- Ensure sensitive fields are in hidden
- Don't use mass assignment for user input
- Ensure relationships are properly authorized
Interview Points
- What is Eloquent ORM and how does it work?
- What is the difference between fillable and guarded?
- What is N+1 query problem and how is it solved?
- What are model events and when are they used?
- What is the difference between chunk() and lazy()?
- What are the benefits of using Eloquent?
Version Notes
- Laravel 11.x: Improved performance in Eloquent queries
- Laravel 11.x: Better support for cursor pagination
- Laravel 10.x: Improved eager loading
- Laravel 9.x: Improved model events