Laravel框架下实现主表字段或关联表字段模糊检索功能问题求助
问题原因分析
- 原代码中
with()方法的闭包条件仅用于过滤预加载的关联patient数据,不会对主表Lab的查询结果产生过滤效果,当前逻辑实际是「查询code匹配的Lab,再为这些Lab附加符合姓名匹配的patient数据」,和「满足code或patient姓名任意一个条件就返回Lab」的需求不符。 - 你在select中定义的
name别名无法直接在where()条件中使用,且直接将$search_query拼接进orWhereRaw存在SQL注入风险。
解决代码
$lab = Lab::query() // 过滤主表:要么code匹配,要么关联的patient姓名匹配 ->where(function ($query) use ($search_query) { $query->where('code', 'like', "%{$search_query}%") ->orWhereHas('patient', function ($q) use ($search_query) { // 用参数绑定避免SQL注入 $q->whereRaw("CONCAT(first_name, ' ', second_name) like ?", ["%{$search_query}%"]); }); }) // 预加载关联的patient数据,不需要额外加过滤条件 ->with(['patient' => function ($q) { $q->select('id', 'avatar', DB::raw('CONCAT(first_Name, " ", second_Name) AS name')); }]) ->select('id', 'code') ->limit(5) ->get();
补充说明
whereHas()的作用就是过滤主表数据,仅返回存在符合闭包条件的关联patient的Lab记录,和主表的code条件用or连接就实现了「满足任意一个条件就返回」的逻辑。- 原生SQL中的变量优先用参数绑定处理,避免SQL注入风险。
- 如果你需要频繁用到拼接好的患者姓名字段,推荐直接在
Patient模型中定义name访问器,不需要每次查询都写DB::raw逻辑。
内容的提问来源于stack exchange,提问作者user17171534
相关产品推荐
相关产品推荐

