Laravel中API Resource集合返回数据无法按gender筛选该如何解决?
问题根因
- 你调用
UserResource::collection()返回的是ResourceCollection实例,不是普通集合,直接调用集合方法遍历的是内部包装的原始Probant模型实例,而不是Resource转换后的数据 - 原始模型的
gender字段是加密存储的,你之前写的filter逻辑里取到的$value->gender是加密后的字符串,自然无法匹配到m;同时你的UserResource里存在逻辑错误:第一个return之后的return parent::toArray($request);永远不会执行,且id被写死为1,所有返回项id都会相同。
最优解决方案(适配加密字段场景,性能优先)
步骤1:给模型添加解密访问器
在Probant模型中添加字段访问器,实现获取gender时自动解密:
// Probant.php public function getGenderAttribute($value) { return \Crypt::decryptString($value); }
步骤2:修正UserResource逻辑
删除无效的return语句,修正id返回逻辑:
// UserResource.php public function toArray($request) { return [ 'gender' => $this->gender, 'id' => $this->id, // 后续扩展字段直接在这里添加即可 ]; }
步骤3:路由层先筛选再返回Resource
Route::get('/test', function() { // 查询所有模型后直接筛选解密后的gender字段 $filteredProbant = Probant::all()->filter(function ($item) { return $item->gender === 'm'; }); // 仅把筛选后的数据集传给Resource做转换 return UserResource::collection($filteredProbant); });
备用方案(在Resource转换后筛选,不推荐)
如果你确实需要先完成Resource转换再筛选,可以先把Resource序列化为数组再处理:
Route::get('/test', function() { $probant = Probant::all(); // 先执行Resource转换拿到最终返回的数组结构 $result = UserResource::collection($probant)->toArray(request()); // 对转换后的数据做筛选 $filteredData = collect($result['data'])->where('gender', 'm'); return response()->json(['data' => $filteredData]); });
该方案的缺点是会先把所有数据都做Resource转换,数据量大的时候会产生不必要的性能开销。
内容的提问来源于stack exchange,提问作者Andreas George Nechita
相关产品推荐
相关产品推荐

