advanced Step 15 of 15

Eloquent Relationships Deep Dive

Laravel Framework

Eloquent Relationships Deep Dive

Eloquent relationships are one of Laravel's most powerful features, allowing you to define and query connections between database tables using expressive, object-oriented syntax. Beyond basic one-to-many and many-to-many relationships, Eloquent supports polymorphic relationships (where a model can belong to multiple types of models), has-one-through and has-many-through (for reaching through intermediate tables), and provides sophisticated eager loading strategies to prevent the dreaded N+1 query problem that can cripple application performance.

Advanced Relationships

<?php
class Post extends Model
{
    // One to Many
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

    // Many to Many with pivot data
    public function tags()
    {
        return $this->belongsToMany(Tag::class)
            ->withPivot('order')
            ->withTimestamps()
            ->orderByPivot('order');
    }

    // Polymorphic — Post and Video can both have Comments
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }

    // Has One Through — get user's country through the user relationship
    public function userCountry()
    {
        return $this->hasOneThrough(Country::class, User::class);
    }
}

// Eager loading strategies
$posts = Post::with('comments.user', 'tags')->get();  // Eager load
$posts = Post::with(['comments' => function ($q) {
    $q->where('approved', true)->latest()->limit(5);
}])->get();

// Lazy eager loading
$posts = Post::all();
$posts->load('comments');

// Count relationships without loading them
$posts = Post::withCount('comments')
    ->having('comments_count', '>', 5)
    ->get();

// Querying relationship existence
$postsWithComments = Post::has('comments', '>=', 3)->get();
$postsWithApproved = Post::whereHas('comments', function ($q) {
    $q->where('approved', true);
})->get();
Pro tip: Use withCount() instead of loading entire relationships when you only need the count. Use whereHas() to filter parents by relationship conditions. Always check your query count with Laravel Debugbar or Telescope to catch N+1 problems early.

Key Takeaways

  • Eloquent supports one-to-one, one-to-many, many-to-many, polymorphic, and has-through relationships.
  • Eager loading (with()) prevents N+1 queries by loading relationships in a single query.
  • Use withCount() for relationship counts and whereHas() to filter by relationship conditions.
  • Pivot tables in many-to-many relationships can store additional data with withPivot().
  • Use Laravel Debugbar or Telescope to monitor query counts and catch performance issues.
arrow_back Events and Listeners check_circle Lap Complete!