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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:15:07