
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.