Laravel 12 API Resource中如何按需加载SKU的Images关联数据?
解决Laravel 12 API Resource中关联字段按需返回的问题
报错原因
whenLoaded是Laravel API Resource类(Illuminate\Http\Resources\Json\JsonResource)的专属方法,仅能在Resource实例上调用。你直接在Sku模型实例$sku上调用该方法,自然会触发Call to undefined method错误。
以下是两种可行的解决方案,按需选择:
方案一:使用子Resource类(推荐,符合Laravel规范)
通过创建Sku和SkuImage对应的Resource类,既能复用逻辑,也能正确使用whenLoaded方法。
1. 创建SkuResource
执行命令生成Resource文件:
php artisan make:resource SkuResource
编辑app/Http/Resources/SkuResource.php:
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class SkuResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, // 补充其他SKU字段 'images' => $this->whenLoaded('images', function () { return SkuImageResource::collection($this->images); }), ]; } }
2. 创建SkuImageResource
执行命令生成Resource文件:
php artisan make:resource SkuImageResource
编辑app/Http/Resources/SkuImageResource.php:
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class SkuImageResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->id, 'filename' => $this->filename, 'size' => $this->size, ]; } }
3. 修改ProductResource中的skus字段
替换原来的map逻辑,直接调用子Resource集合:
'skus' => $this->whenLoaded('skus', function () { return SkuResource::collection($this->skus); }),
这样当你用with(['skus'])加载时,返回的SKU数据不会包含images字段;用with(['skus.images'])加载时,会自动带上图片数据。
方案二:直接用模型的relationLoaded方法判断
如果不想创建子Resource,可直接在ProductResource中通过模型的relationLoaded方法检查关联是否已加载:
'skus' => $this->whenLoaded('skus', function () { return $this->skus->map(function ($sku) { $skuData = [ 'id' => $sku->id, // 补充其他SKU字段 ]; // 仅当images关联被预加载时,才添加该字段 if ($sku->relationLoaded('images')) { $skuData['images'] = $sku->images->map(function ($image) { return [ 'id' => $image->id, 'filename' => $image->filename, 'size' => $image->size, ]; }); } return $skuData; }); }),
内容的提问来源于stack exchange,提问作者calin24
相关产品推荐
相关产品推荐

