Laravel 8过滤Project与Reservations嵌套关联表出现mb_strpos错误如何解决
错误原因
with关联预加载语法错误:你传入的参数格式为["reservations", function($query){}],Laravel会将数组的每个元素都识别为要预加载的关联名称,第二个元素是闭包对象,被当作字符串传入处理关联名的mb_strpos方法,直接触发报错。带条件的关联预加载需要使用键值对格式,关联名为键,过滤闭包为值:["reservations" => function($query){}]- 查询逻辑顺序错误:
Project::find($id)已经执行SQL返回了单条项目模型实例,后续再调用with和get属于冗余操作,get会再次查询返回全量项目列表,不符合你获取单个指定项目的需求。 - Project模型定义了全局自动预加载属性
$with = ["reservations"],不做特殊处理会额外加载未过滤的预约数据。
正确实现代码
$startDate = $request->get("startDate"); $endDate = $request->get("endDate"); // 方法1:直接查询指定项目,同时预加载过滤后的预约,临时取消默认自动预加载避免重复加载 return Project::without('reservations') ->where('id', $id) ->with(['reservations' => function($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }]) ->first(); // 方法2:如果已经拿到项目实例,可以直接懒加载过滤后的关联 $project = Project::find($id); $project->load(['reservations' => function($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }]); return $project;
补充说明
如果你需要筛选「至少存在一条符合日期范围预约的项目」,避免返回项目但关联预约为空的情况,可以加上whereHas条件:
return Project::without('reservations') ->where('id', $id) ->whereHas('reservations', function($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }) ->with(['reservations' => function($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }]) ->first();
内容的提问来源于stack exchange,提问作者yvl
相关产品推荐
相关产品推荐

