Eloquent Relationship Queries in Laravel with whereRelation

Last updated: 3 months ago By : Dishant Ved

whereRelation

Laravel's whereRelation method streamlines the process of filtering models based on their relationships' attributes. This elegant approach replaces complex subqueries and joins with a more readable and maintainable syntax.


This feature proves especially valuable when building complex filters in e-commerce platforms, content management systems, or any application where models are interconnected and filtering based on related data is crucial.

Post::whereRelation('comments', 'is_approved', true)->get();


Here's an example of building a course filtering system:

<?php
 
namespace App\Http\Controllers;
 
use App\Models\Course;
use Illuminate\Http\Request;
 
class CourseController extends Controller
{
    public function browse(Request $request)
    {
        $courses = Course::query();
        // Filter by instructor rating
        if ($request->has('top_rated')) {
            $courses->whereRelation(
                'instructor',
                'rating',
                '>=',
                4.5
            );
        }
 
        // Filter by recent student reviews
        if ($request->has('well_reviewed')) {
            $courses->orWhereRelation(
                'reviews',
                'created_at',
                '>=',
                now()->subDays(30)
            );
        }
 
        // Filter by active discussion
        if ($request->has('active_discussion')) {
            $courses->whereRelation(
                'discussions',
                'last_activity',
                '>=',
                now()->subDays(7)
            );
        }
        return $courses->with(['instructor', 'reviews'])
            ->latest()
            ->paginate();
    }
}


The query builder creates efficient SQL based on your relationship conditions:

// Filters courses with:
// - Highly rated instructors (4.5+)
// - OR recent reviews
// - AND active discussions
$courses = Course::whereRelation('instructor', 'rating', '>=', 4.5)
    ->orWhereRelation('reviews', 'created_at', '>=', now()->subDays(30))
    ->whereRelation('discussions', 'last_activity', '>=', now()->subDays(7))
    ->get();


WhereRelation provides a clean, expressive way to filter models based on relationship attributes, leading to more maintainable code.