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.

ORMPHPLaravelActive RecordWeb Development

GitHub Overview

laravel/framework

The Laravel Framework.

Stars33,844
Watchers958
Forks11,444
Created:January 10, 2013
Language:PHP
License:MIT License

Topics

frameworklaravelphp

Star History

laravel/framework Star History
Data as of: 7/19/2025, 09:31 AM

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'));
    }
}