beginner Step 3 of 15

Eloquent ORM

Laravel Framework

Eloquent ORM

Eloquent is Laravel's Active Record ORM (Object-Relational Mapper) that provides a beautiful, expressive way to interact with your database. Each database table has a corresponding Model class used to query and manipulate data. Eloquent supports relationships (one-to-one, one-to-many, many-to-many), eager loading, scopes, accessors, mutators, events, and much more. It is one of the most feature-rich and developer-friendly ORMs in any language.

Models and Queries

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model
{
    use SoftDeletes;

    protected $fillable = ['title', 'body', 'category', 'published_at'];
    protected $casts = [
        'published_at' => 'datetime',
        'is_featured' => 'boolean',
    ];

    // Relationships
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }

    // Scopes
    public function scopePublished($query)
    {
        return $query->whereNotNull('published_at')->where('published_at', '<=', now());
    }

    public function scopeByCategory($query, string $category)
    {
        return $query->where('category', $category);
    }

    // Accessor
    public function getExcerptAttribute(): string
    {
        return str()->limit($this->body, 150);
    }
}

// Querying
$posts = Post::all();
$post = Post::find(1);
$post = Post::findOrFail(1);  // Throws 404 if not found

// Query builder
$posts = Post::where('category', 'tech')
    ->where('published_at', '<=', now())
    ->orderBy('published_at', 'desc')
    ->limit(10)
    ->get();

// Using scopes
$techPosts = Post::published()->byCategory('tech')->paginate(15);

// Eager loading (prevents N+1 queries)
$posts = Post::with(['user', 'comments', 'tags'])->get();

// Create
$post = Post::create([
    'title' => 'My Post',
    'body' => 'Content here',
    'user_id' => auth()->id(),
]);

// Update
$post->update(['title' => 'Updated Title']);

// Delete
$post->delete();       // Soft delete (with SoftDeletes trait)
$post->forceDelete();  // Permanent delete
Pro tip: Always use eager loading (Post::with('comments')) when you know you will access relationships. Without it, accessing $post->comments in a loop triggers a separate query for each post (the N+1 problem). Use php artisan make:model Post -m to generate both model and migration together.

Key Takeaways

  • Eloquent maps database tables to Model classes with automatic timestamps and query building.
  • Define relationships with belongsTo(), hasMany(), belongsToMany(), etc.
  • Use eager loading (with()) to prevent N+1 query problems.
  • Scopes provide reusable query constraints: Post::published()->get().
  • Protect against mass assignment with $fillable or $guarded properties.