Laravel中如何合并Collection与查询构造器结果后实现分页
错误原因
你遇到的报错是因为Laravel查询构建器的union()方法仅支持传入另一个查询构建器(QueryBuilder)实例,但你传入的$processingRequests是已经调用get()执行查询后得到的Collection集合,类型不匹配导致调用方法失败。
解决方案
由于处理中的请求数据量极小(仅10条左右),你可以先提取校验通过的处理中请求ID,再将ID合并到已关闭请求的查询条件中,得到统一的查询构建器后再执行分页,完全避开union的类型问题,同时不会产生额外性能开销。
基础实现代码(处理中请求存在request_logs关联记录时可用)
public function getRequests(){ // 先获取校验通过的处理中请求ID数组 $validProcessingIds = request::select("requests.id", "requests.user_id", "requests.form_type", "requests.created_at", "requests.request_status") ->where('request_status', 0) ->get() ->filter(function ($request) { return FormsController::checkUserPermissionToConsultForm($request, true); }) ->pluck('id') ->toArray(); // 构造统一查询:已关闭的有权限请求 + 校验通过的处理中请求 $allRequests = request::join('request_logs', 'request_logs.request_id', '=', 'requests.id') ->select("requests.id", "requests.user_id", "requests.form_type", "requests.created_at", "requests.request_status") ->where(function ($query) use ($validProcessingIds) { // 原有已关闭请求的权限条件 $query->whereNotIn('request_status', [-2, 0]) ->where('request_logs.user_id', Auth::user()->id); // 追加校验通过的处理中请求 if (!empty($validProcessingIds)) { $query->orWhereIn('requests.id', $validProcessingIds); } }) ->orderBy('created_at', 'desc') ->paginate(5); return $allRequests; }
适配场景:处理中请求无对应request_logs记录
如果处理中的请求还未生成关联日志,可将关联改为左连接并拆分条件,避免处理中请求被过滤:
public function getRequests(){ $validProcessingIds = request::select("requests.id", "requests.user_id", "requests.form_type", "requests.created_at", "requests.request_status") ->where('request_status', 0) ->get() ->filter(function ($request) { return FormsController::checkUserPermissionToConsultForm($request, true); }) ->pluck('id') ->toArray(); $allRequests = request::leftJoin('request_logs', 'request_logs.request_id', '=', 'requests.id') ->select("requests.id", "requests.user_id", "requests.form_type", "requests.created_at", "requests.request_status") ->where(function ($query) use ($validProcessingIds) { // 已关闭请求需要满足日志关联权限 $query->where(function ($q) { $q->whereNotIn('request_status', [-2, 0]) ->where('request_logs.user_id', Auth::user()->id); }); // 处理中请求只要在合法ID数组内即可 if (!empty($validProcessingIds)) { $query->orWhereIn('requests.id', $validProcessingIds); } }) ->orderBy('created_at', 'desc') ->paginate(5); return $allRequests; }
注意事项
模型名建议遵循Laravel规范使用大驼峰命名,避免和请求门面Request产生混淆。
内容的提问来源于stack exchange,提问作者Achraf Ben Soltane
相关产品推荐
相关产品推荐

