编程

Laravel 使用 whereRelation 进行 Eloquent 关联查询

74 2025-03-03 03:32:00

Laravel 的 whereRelation 方法简化了基于关联属性过滤模型的处理。这个优雅的方式代替复杂的子查询,加入了更具可读性以及更可维护的语法。

在电子商务平台、内容管理系统或任何模型相互连接且基于相关数据进行过滤至关重要的应用中构建复杂过滤器时,此功能特别有价值。

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

以下是创建课程(Course)过滤系统的示例:

<?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();
    }
}

该查询构造器基于关联条件创建了高效的 SQL:

// 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 提供了一个简洁、富有表现力的方式来基于关联属性过滤模型,从而产生更易于维护的代码。

 

下一篇