Laravel 格式资源集合响应报错 Property [product_id] does not exist on this collection instance

Posted

技术标签:

【中文标题】Laravel 格式资源集合响应报错 Property [product_id] does not exist on this collection instance【英文标题】:Laravel format resource collection response error Property [product_id] does not exist on this collection instance 【发布时间】:2021-01-29 05:00:09 【问题描述】:

在 laravel 中,我们可以格式化来自资源类的 json 响应,如下所示

class ProductsResource extends JsonResource

    public function toArray($request)
        
            return [
                'id'=> $this->product_id ,
                'code'=> $this->product_code,
                'shortdescription'=> $this->product_short_description,
                'image'=> $this->product_image,
                
            ];
        

但是当返回资源集合时,我无法格式化我的集合错误属性 [product_id] 在此集合实例上不存在

class ProductsResource extends ResourceCollection

    public function toArray($request)
        
            return [
                'id'=> $this->product_id ,
                'code'=> $this->product_code,
                'shortdescription'=> $this->product_short_description,
                'image'=> $this->product_image,
                
            ];
        

谢谢。

【问题讨论】:

【参考方案1】:

这是因为 ResourceCollection 需要 collection 的项目而不是 single item。集合资源希望您遍历集合,并且不能直接从 $this 执行单个实体例程(因为它是一个集合)。

See resource collections in documentation

您可能正在寻找的是可以在此处找到示例的自定义突变:

See custom casts in documentation

查找/搜索Value Object Casting。它详细解释了如何改变getset 上的属性,这可能比资源集合更好(如果这是您唯一希望用它做的事情)。这将立即修改集合,让您不必在每次需要时手动实例化资源集合(因为您在模型级别进行修改)。

来自文档:

Value Object Casting 您不仅限于将值转换为原始类型。您还可以将值转换为对象。定义将值转换为对象的自定义转换与转换为原始类型非常相似;但是,set 方法应该返回一个键/值对数组,用于在模型上设置原始的、可存储的值。

但是要回到主题...

如果你转储并死掉:dd($this);,你会看到有一个名为+collection的属性

如果您希望转换键或值,则必须遍历 $this->collection 以将集合 valueskeys 转换为您的要求。

正如您在父类Illuminate\Http\Resources\Json\ResourceCollection 中看到的,方法toArray() 已经是一个映射集合。

您可以在其中看到它指向$this->collection

/**
 * Transform the resource into a JSON array.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)

    return $this->collection->map->toArray($request)->all();

您可以使用以下内容。并更新此集合映射中的项目/键值。

return $this->collection->map(function($item, $key))->toArray();

如果您希望在将值返回到数组之前对其进行转换。

或像这样的简单 foreach(尚未对其进行测试,并且有更好的方法)但是为了分享 simple-to-grasp 示例:

$result = [];

// Map the associations to be modified
$resultMap = [
    'product_id'                 => 'id',
    'product_code'               => 'code',
    'product_short_description'  => 'shortdescription',
    'product_image'              => 'image'
];

// Iterate through the collection
foreach ($this->collection as $index => $item)
    foreach ($item as $key => $value)
        $result[$index][$resultMap[$key]] = $value;

return $result;

【讨论】:

我没有很好的解释。真的谢谢。接受

以上是关于Laravel 格式资源集合响应报错 Property [product_id] does not exist on this collection instance的主要内容,如果未能解决你的问题,请参考以下文章

向 laravel 中的资源 json 响应添加状态和消息键

Laravel API 资源集合从其他资源返回特定字段

使用 Laravel 资源将字段数据格式化为字典

Laravel API resourceCollection 使用数组而不是模型

用于 API 响应的 Laravel 自定义包装器

php Laravel资源将其他数据传递给资源和集合