Laravel 5.6 Eloquent多表带参数查询方法及问题求助
解决Laravel 5.6多表关联查询的过滤问题
你遇到的问题其实是Laravel关联查询里的常见误区:with()方法里的闭包只会过滤关联模型的返回数据,但不会影响主模型(Casefile)的查询结果,也不会自动过滤其他关联(比如client、section)。所以哪怕你给loan加了条件,所有Casefile还是会被返回,只是它们的loan关联只包含符合条件的记录,而client和section则会加载全部数据。
要实现“仅返回与给定参数匹配的记录”,你需要结合whereHas()来约束主模型,同时按需过滤其他关联:
基础解决方案(仅过滤loan关联并约束主模型)
Casefile::with([ 'client', // 若不需要过滤client,直接保留即可 'loan' => function($query) use($request) { $query->where('bank_name', 'REGEXP', $request->bank_name); }, 'section' // 同理,不需要过滤就直接写关联名 ]) // 关键:用whereHas确保只有包含符合条件loan的Casefile才被返回 ->whereHas('loan', function($query) use($request) { $query->where('bank_name', 'REGEXP', $request->bank_name); }) // 这里可以继续添加Casefile自身的查询条件,比如你原来的where(...) ->get();
扩展:同时过滤其他关联(比如client或section)
如果你的需求里client或section也需要根据POST参数过滤,同样的逻辑:在with()里加闭包筛选关联数据,用whereHas()约束主模型(如果需要主模型只保留有匹配关联的记录):
Casefile::with([ 'client' => function($query) use($request) { // 示例:按客户名称模糊匹配 $query->where('name', 'like', "%{$request->client_name}%"); }, 'loan' => function($query) use($request) { $query->where('bank_name', 'REGEXP', $request->bank_name); }, 'section' => function($query) use($request) { // 示例:按部门ID匹配 $query->where('id', $request->section_id); } ]) ->whereHas('loan', function($query) use($request) { $query->where('bank_name', 'REGEXP', $request->bank_name); }) // 如果需要主模型仅保留有匹配client的记录,添加这个whereHas ->whereHas('client', function($query) use($request) { $query->where('name', 'like', "%{$request->client_name}%"); }) ->get();
关键知识点梳理
with():预加载关联数据,闭包用来筛选要加载的关联记录,但不会影响主模型的查询结果。whereHas():过滤主模型,只保留存在符合条件关联的主模型记录,相当于给主模型加了关联条件的约束。- 如果你只是想加载筛选后的关联数据,但允许主模型存在没有匹配关联的情况(比如某些Casefile没有符合条件的loan,但仍要返回这些Casefile,只是loan关联为空),那只需要保留
with()里的闭包即可,但这不符合你“仅返回匹配参数记录”的需求。
另外提醒下:使用REGEXP时要确保$request->bank_name是合法的正则表达式,避免潜在的安全风险;如果不需要正则匹配,用like会更简单安全。
内容的提问来源于stack exchange,提问作者netdjw
相关产品推荐
相关产品推荐

