Laravel 8分页后使用map加计算字段报links方法不存在如何解决?
问题原因
你遇到的报错确实是因为分页对象调用map方法后类型变更导致:Laravel的LengthAwarePaginator分页实例调用map方法时会返回普通的Illuminate\Database\Eloquent\Collection集合对象,丢失了原分页实例的links()、total()等分页相关方法与属性。
修复方案
方案1(推荐):使用分页器自带的through方法替代map
through是Laravel分页器专门提供的用于遍历处理分页项的方法,处理逻辑和map完全一致,执行完成后会保留原分页实例,不会丢失分页属性,Laravel 8版本完全支持该方法。
修改后代码如下:
$hostelDataRows = Hostel ::orderBy('created_at', 'desc') ->where('hostels.id', 41) // debug ->with('state') ->with('region') ->with('user') ->withCount('hostelRooms') ->withCount('hostelInquiries') ->withCount('hostelImages') ->getByName($this->filters['name'], true) ->getByStatus($this->filters['status'], true) ->getByStateId($this->filters['state_id'], true) ->getByFeature($this->filters['feature'], true) ->addSelect([ 'min_hostel_rooms_price' => HostelRoom::query() ->selectRaw('MIN(price)') ->whereColumn('hostel_id', 'hostels.id'), ]) ->paginate($backend_per_page) // 仅将map替换为through即可,内部逻辑无需修改 ->through(function ($hostelItem) { if ($hostelItem->hostel_rooms_count > 0 and $hostelItem->hostel_inquiries_count > 0 and $hostelItem->hostel_images_count > 0 ) { $hostelItem->info_text = 'Has ' . ($hostelItem->hostel_rooms_count . pluralize3( $hostelItem->hostel_rooms_count, 'no rooms', 'room', 'rooms' ) ); } return $hostelItem; }) ;
方案2:手动将处理后的集合写回分页实例
如果你需要单独对集合做更复杂的操作,也可以先获取分页实例,处理完集合后手动回写:
// 先获取原始分页实例 $paginator = Hostel::orderBy('created_at', 'desc') // 省略中间的查询逻辑,和原代码一致 ->paginate($backend_per_page); // 处理分页项集合 $processedItems = $paginator->getCollection()->map(function ($hostelItem) { // 你的原有处理逻辑 if ($hostelItem->hostel_rooms_count > 0 and $hostelItem->hostel_inquiries_count > 0 and $hostelItem->hostel_images_count > 0 ) { $hostelItem->info_text = 'Has ' . ($hostelItem->hostel_rooms_count . pluralize3( $hostelItem->hostel_rooms_count, 'no rooms', 'room', 'rooms' ) ); } return $hostelItem; }); // 将处理后的集合写回分页实例 $paginator->setCollection($processedItems); $hostelDataRows = $paginator;
内容的提问来源于stack exchange,提问作者mstdmstd
相关产品推荐
相关产品推荐

