0

在 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,
                
            ];
        }
}

谢谢。

4

1 回答 1

1

这是因为ResourceCollection期望 a collectionof items 而不是 a single item。集合资源希望您遍历集合并且不能直接从$this(因为它是一个集合)执行单个实体例程。

请参阅文档中的资源集合

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

请参阅文档中的自定义演员表

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

来自文档:

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;
于 2020-10-14T20:18:53.390 回答