Laravel Eloquent
Laravel Eloquent is the Active Record implementation ORM of the Laravel framework. It enables intuitive database operations through elegant and fluent API, providing rich features including relationships, events, accessors/mutators, and more.
GitHub Overview
laravel/framework
The Laravel Framework.
Topics
Star History
Library
Laravel Eloquent
Overview
Laravel Eloquent is the Active Record implementation ORM of the Laravel framework. It enables intuitive database operations through elegant and fluent API, providing rich features including relationships, events, accessors/mutators, and more.
Details
Eloquent ORM is designed to express database operations in beautiful and expressive PHP code. It adopts the Active Record pattern, executing CRUD operations through model classes corresponding to each database table. Deep integration with the Laravel ecosystem works in conjunction with related features like migrations, factories, and seeders to support efficient web development.
Key Features
- Fluent API: Intuitive and readable method chaining
- Relationships: Rich relationship definition capabilities
- Eloquent Collections: Powerful data manipulation methods
- Events: Hook functionality in model lifecycle
- Casting: Automatic type conversion capabilities
Pros and Cons
Pros
- Intuitive API that's easy for PHP developers to learn
- Complete integration with Laravel ecosystem
- Rich relationship features enable concise expression of complex data structures
- Flexible data transformation through accessors/mutators
- High development productivity for small to medium-scale projects
Cons
- Performance challenges in large-scale systems
- Tight coupling of business logic and data access due to Active Record pattern
- Limited expression for complex queries in some cases
- Difficult to use with other frameworks due to Laravel framework dependency
Reference Pages
Code Examples
Installation and Basic Setup
# Create Laravel project
composer create-project laravel/laravel myproject
cd myproject
# Database setup
php artisan make:migration create_users_table
php artisan make:migration create_posts_table
// .env file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=
// config/database.php (adjust as needed)
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
],
Basic CRUD Operations (Model Definition, Create, Read, Update, Delete)
// app/Models/User.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class User extends Model
{
use HasFactory;
protected $fillable = [
'name',
'email',
'email_verified_at',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
// Relationships
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
}
// app/Models/Post.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'title',
'content',
'user_id',
'published_at',
];
protected $casts = [
'published_at' => 'datetime',
];
// Relationships
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
// Run migrations
// php artisan migrate
// Basic CRUD operations
use App\Models\User;
use App\Models\Post;
// Create
$user = User::create([
'name' => 'John Doe',
'email' => '[email protected]',
'password' => bcrypt('password123'),
]);
// Read
$allUsers = User::all();
$userById = User::find(1);
$userByEmail = User::where('email', '[email protected]')->first();
// Update
$user = User::find(1);
$user->name = 'John Smith';
$user->save();
// Bulk update
User::where('name', 'like', '%John%')->update(['status' => 'active']);
// Delete
$user = User::find(1);
$user->delete();
// Bulk delete
User::where('status', 'inactive')->delete();
Advanced Queries and Relationships
// Complex conditional queries
$activeUsers = User::where('status', 'active')
->where('created_at', '>=', now()->subDays(30))
->where('email', 'like', '%@company.com')
->orderBy('created_at', 'desc')
->limit(10)
->get();
// Relationship queries
$usersWithPosts = User::with('posts')->get();
$usersWithRecentPosts = User::with(['posts' => function ($query) {
$query->where('created_at', '>=', now()->subDays(7))
->orderBy('created_at', 'desc');
}])->get();
// Conditional relationship loading
$users = User::when(request('include_posts'), function ($query) {
return $query->with('posts');
})->get();
// Aggregation queries
$userStats = User::selectRaw('
COUNT(*) as total_users,
AVG(posts_count) as avg_posts_per_user,
MAX(created_at) as latest_user_date
')
->withCount('posts')
->first();
// Subqueries
$activeUsers = User::whereHas('posts', function ($query) {
$query->where('published_at', '>=', now()->subDays(30));
})->get();
// Join queries
$postsWithAuthors = Post::join('users', 'posts.user_id', '=', 'users.id')
->select('posts.*', 'users.name as author_name')
->where('posts.published_at', '>=', now()->subDays(7))
->get();
// Scope queries
class User extends Model
{
public function scopeActive($query)
{
return $query->where('status', 'active');
}
public function scopeWithRecentPosts($query, $days = 30)
{
return $query->whereHas('posts', function ($q) use ($days) {
$q->where('created_at', '>=', now()->subDays($days));
});
}
}
// Using scopes
$activeUsersWithRecentPosts = User::active()
->withRecentPosts(7)
->get();
Migrations and Schema Management
# Create migrations
php artisan make:migration create_users_table
php artisan make:migration add_status_to_users_table
# Run migrations
php artisan migrate
# Rollback migrations
php artisan migrate:rollback
php artisan migrate:rollback --step=3
# Check migration status
php artisan migrate:status
// database/migrations/xxxx_create_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->enum('status', ['active', 'inactive'])->default('active');
$table->rememberToken();
$table->timestamps();
$table->index(['status', 'created_at']);
$table->index('email');
});
}
public function down(): void
{
Schema::dropIfExists('users');
}
};
// database/migrations/xxxx_create_posts_table.php
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamp('published_at')->nullable();
$table->timestamps();
$table->index(['user_id', 'published_at']);
$table->index('published_at');
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
Performance Optimization and Advanced Features
// Transactions
use Illuminate\Support\Facades\DB;
DB::transaction(function () {
$user = User::create([
'name' => 'Jane Doe',
'email' => '[email protected]',
'password' => bcrypt('password123'),
]);
Post::create([
'title' => 'First Post',
'content' => 'My first post using Laravel Eloquent',
'user_id' => $user->id,
'published_at' => now(),
]);
});
// Batch operations
$userData = [
['name' => 'User 1', 'email' => '[email protected]', 'password' => bcrypt('password')],
['name' => 'User 2', 'email' => '[email protected]', 'password' => bcrypt('password')],
['name' => 'User 3', 'email' => '[email protected]', 'password' => bcrypt('password')],
];
User::insert($userData);
// Batch update (Laravel 8+)
User::whereIn('id', [1, 2, 3])->update(['status' => 'verified']);
// Chunk processing (large datasets)
User::chunk(100, function ($users) {
foreach ($users as $user) {
// Processing logic
$user->process();
}
});
// Eager loading to avoid N+1 problem
$posts = Post::with('user')->get();
// Lazy eager loading
$posts = Post::all();
$posts->load('user');
// Custom casting
class User extends Model
{
protected $casts = [
'preferences' => 'array',
'last_login_at' => 'datetime',
'is_admin' => 'boolean',
];
}
// Accessors and Mutators
class User extends Model
{
// Accessor
public function getFullNameAttribute(): string
{
return $this->first_name . ' ' . $this->last_name;
}
// Mutator
public function setPasswordAttribute($value): void
{
$this->attributes['password'] = bcrypt($value);
}
}
// Model events
class User extends Model
{
protected static function boot()
{
parent::boot();
static::creating(function ($user) {
$user->uuid = Str::uuid();
});
static::created(function ($user) {
// Post-creation processing
Mail::to($user)->send(new WelcomeEmail());
});
}
}
// Query builder optimization
$users = User::select(['id', 'name', 'email'])
->where('status', 'active')
->orderBy('created_at', 'desc')
->paginate(15);
Framework Integration and Practical Examples
// API Resource Controller
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class UserController extends Controller
{
public function index(): JsonResponse
{
$users = User::with('posts')
->paginate(15);
return response()->json($users);
}
public function show(User $user): JsonResponse
{
$user->load('posts');
return response()->json($user);
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:8',
]);
$user = User::create($validated);
return response()->json($user, 201);
}
public function update(Request $request, User $user): JsonResponse
{
$validated = $request->validate([
'name' => 'sometimes|string|max:255',
'email' => 'sometimes|email|unique:users,email,' . $user->id,
]);
$user->update($validated);
return response()->json($user);
}
public function destroy(User $user): JsonResponse
{
$user->delete();
return response()->json(['message' => 'User deleted successfully']);
}
}
// Job Queue Integration
<?php
namespace App\Jobs;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessUserData implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
private User $user
) {}
public function handle(): void
{
// Execute heavy processing in background
$this->user->update([
'processed_at' => now(),
'status' => 'processed',
]);
}
}
// Job dispatch
ProcessUserData::dispatch($user);
// Factory and Seeder
// database/factories/UserFactory.php
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => bcrypt('password'),
'remember_token' => Str::random(10),
];
}
}
// database/seeders/UserSeeder.php
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
public function run(): void
{
User::factory()
->count(50)
->hasPosts(3)
->create();
}
}
// Blade template usage
{{-- resources/views/users/index.blade.php --}}
@extends('layouts.app')
@section('content')
<div class="container">
<h1>User List</h1>
@foreach ($users as $user)
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{ $user->name }}</h5>
<p class="card-text">{{ $user->email }}</p>
<p class="card-text">
<small class="text-muted">
Posts: {{ $user->posts_count }}
</small>
</p>
</div>
</div>
@endforeach
{{ $users->links() }}
</div>
@endsection
// Controller
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index()
{
$users = User::withCount('posts')
->paginate(10);
return view('users.index', compact('users'));
}
}