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

如何在Laravel中结合OR条件使用whereBelongsTo方法?

问题原因与解决方案

你的问题出在逻辑条件的分组优先级上,当前写法会导致归属条件脱离了原有查询的过滤规则(比如软删除deleted_at、管理员权限限制),最终导致无结果返回。

具体问题分析

你原来的代码中,当找到匹配的会员中心时,是这样拼接条件的:

$query->where(/* 搜索条件闭包 */)
      ->orWhere(/* 归属条件闭包 */);

结合之前已有的deleted_at和管理员权限过滤,最终生成的SQL逻辑是:

WHERE deleted_at IS NULL 
AND (created_by = ? OR regional_center_id = ?)
AND (搜索条件)
OR (归属条件)

由于SQL中AND优先级高于OR,这段逻辑等价于:
(原有条件 AND 搜索条件) OR (归属条件)
这里的归属条件没有带上deleted_at和管理员权限的过滤,要么查不到符合要求的记录,要么查到的是不符合权限/已删除的记录,自然返回空。

而你单独使用whereBelongsTo时,逻辑是:
原有条件 AND 归属条件
所有过滤规则都生效,所以能返回正确结果。

修复后的代码

把搜索条件和归属条件放到同一个外层闭包里,让它们共享原有条件的过滤,逻辑变成原有条件 AND (搜索条件 OR 归属条件):

if(isset($request->searchKey) && !empty($request->searchKey) && $request->searchKey !== '')
{  
    $data['searchKey']  = $request->searchKey;
    $searchKey          = trim($data['searchKey']);
    $membershipCenters  = MembershipCenter::where('name', 'LIKE', '%' . $searchKey . '%')->get();

    // 用集合的isNotEmpty()简化判断
    if($membershipCenters->isNotEmpty()) {
        $query->where(function ($mainOrQuery) use ($searchKey, $membershipCenters) {
            // 原有搜索条件
            $mainOrQuery->where(function ($orQuery) use ($searchKey){
                $orQuery->where('name', 'LIKE', '%' . $searchKey . '%')
                    ->orWhere('mobile', 'LIKE', '%' . $searchKey . '%')
                    ->orWhere('card_id', 'LIKE', '%' . $searchKey . '%')
                    ->orWhereHas('employeeLanguage', function ($languageRelationQuery) use ($searchKey){
                        $languageRelationQuery->where(function($languageQueryEn) use($searchKey) {
                                                    $languageQueryEn->where('name', 'LIKE', '%' . $searchKey . '%')
                                                                    ->where('language', 'en');
                                                })
                                                ->orWhere(function($olanguageQueryAr) use($searchKey) {
                                                    $olanguageQueryAr->where('name', 'LIKE', '%' . $searchKey . '%')
                                                                    ->where('language', 'ar');
                                                });
                    });
            })
            // 把归属条件放到同一个外层闭包的OR分支里
            ->orWhere(function($belongsToQuery) use($membershipCenters) {
                $belongsToQuery->whereBelongsTo($membershipCenters, 'employeeMembershipCenter');
            });
        });
    } else {
        // 原有搜索逻辑不变
        $query->where(function ($orQuery) use ($searchKey){
                $orQuery->where('name', 'LIKE', '%' . $searchKey . '%')
                        ->orWhere('mobile', 'LIKE', '%' . $searchKey . '%')
                        ->orWhere('card_id', 'LIKE', '%' . $searchKey . '%')
                        ->orWhereHas('employeeLanguage', function ($languageRelationQuery) use ($searchKey){
                            $languageRelationQuery->where(function($languageQueryEn) use($searchKey) {
                                                        $languageQueryEn->where('name', 'LIKE', '%' . $searchKey . '%')
                                                                        ->where('language', 'en');
                                                    })
                                                    ->orWhere(function($olanguageQueryAr) use($searchKey) {
                                                        $olanguageQueryAr->where('name', 'LIKE', '%' . $searchKey . '%')
                                                                        ->where('language', 'ar');
                                                    });
                        });
            });
    }
}

额外优化点

Laravel集合自带isNotEmpty()方法,可以替代繁琐的isset() && !empty() && count() > 0判断,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:48:10