You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何基于关联模型实现订单精准搜索?

订单搜索查询问题:仅显示匹配结果而非关联用户/分类下全部订单

我有两个关联模型,现在尝试对订单进行搜索,希望仅显示实际匹配搜索关键词的订单结果,而不是只要找到匹配的用户或分类,就返回该用户/分类下的全部订单。


数据库迁移代码(orders表)

public function up()
{
    Schema::create('orders', function (Blueprint $table) {
        $table->id();
        $table->foreignId('user_id')->constrained()->cascadeOnDelete();
        $table->foreignId('category_id')->constrained()->cascadeOnDelete();
        $table->foreignId('report_id')->constrained()->cascadeOnDelete();
        $table->string('time');
        $table->string('date');
        $table->integer('issue_number');
        $table->boolean('status');
        $table->text('description')->nullable();
        $table->timestamps();
    });
}

原查询逻辑(OrderController.php)

原代码存在两处关键问题:一是单个ID筛选误用whereIn(该方法用于数组集合);二是OR条件的包裹逻辑错误,导致会跳出用户/分类的基础筛选,返回不符合要求的订单:

public function index()
{
    $keyword = request('search') ?? null;
    $orders = Order::query()->whereIn('user_id', $user->id)->whereIn('category_id', $category->id)
        ->orWhere(function ($query) use ($keyword) {
            $query->when($keyword, function ($query) use ($keyword) {
                $query->where('first_name' , 'LIKE' , "%{$keyword}%");
            });
        })->latest()->paginate(25);
    return view('Admin.orders.index', compact('orders'));
}

Order模型关联定义(Order.php)

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

public function report()
{
    return $this->belongsTo(Report::class);
}

public function category()
{
    return $this->belongsTo(Category::class);
}

修正后的查询逻辑

要实现精准搜索,需调整逻辑结构,确保搜索条件不会打破基础的用户/分类筛选:

情况1:搜索订单自身字段(如描述、订单号等)

public function index()
{
    $keyword = request('search') ?? null;
    $orders = Order::query()
        // 基础筛选:锁定指定用户和分类
        ->where('user_id', $user->id)
        ->where('category_id', $category->id)
        // 仅当有搜索关键词时,添加匹配逻辑
        ->when($keyword, function ($query) use ($keyword) {
            $query->where(function ($q) use ($keyword) {
                // 可根据需求添加更多订单自身字段
                $q->where('description', 'LIKE', "%{$keyword}%")
                  ->orWhere('issue_number', 'LIKE', "%{$keyword}%")
                  ->orWhere('date', 'LIKE', "%{$keyword}%");
            });
        })
        ->latest()
        ->paginate(25);

    return view('Admin.orders.index', compact('orders'));
}

情况2:搜索关联用户的first_name字段

如果要搜索用户的名称,必须用whereHas关联查询,确保只返回该用户下匹配名称的订单:

public function index()
{
    $keyword = request('search') ?? null;
    $orders = Order::query()
        ->where('user_id', $user->id)
        ->where('category_id', $category->id)
        ->when($keyword, function ($query) use ($keyword) {
            $query->where(function ($q) use ($keyword) {
                // 匹配订单自身字段
                $q->where('description', 'LIKE', "%{$keyword}%")
                  // 匹配关联用户的first_name
                  ->orWhereHas('user', function ($userQuery) use ($keyword) {
                      $userQuery->where('first_name', 'LIKE', "%{$keyword}%");
                  });
            });
        })
        ->latest()
        ->paginate(25);

    return view('Admin.orders.index', compact('orders'));
}

核心逻辑说明

  • 单个ID筛选用where('user_id', $user->id),whereIn仅适用于数组类型的筛选条件(如whereIn('user_id', [1,2,3]))
  • 搜索条件嵌套在where闭包内,确保OR逻辑只在搜索字段之间生效,不会干扰外层的用户/分类基础筛选
  • 关联模型字段必须用whereHas查询,不能直接写where('first_name')(因为first_name不在orders表中)

内容的提问来源于stack exchange,提问作者Ashraf Khosravi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:24:10