首页 > 解决方案 > 如何在 API 资源中使用条件关系?

问题描述

我创建了一个 API 资源:

class OrderResource extends JsonResource
{

    public function toArray($request)
    {
        return [
            "id" => $this->Id,
            "photo" => ''
        ];
    }
}

在控制器中,我从模型OrderModel中获取数据,将数据放入资源中OrderResource

public function show($id)
{
        $order = OrderModel::with('OrderPhoto')->findOrFail(1);

        return new OrderResource($order);
}

OrderPhoto所以,我尝试OrderResource像这样使用关系:

public function toArray($request)
    {
        return [
            "id" => $this->Id,
            "photo" => OrderPhotoResource::collection($this->whenLoaded('OrderPhoto')),
        ];
    }

但它不起作用并给出此错误:

未定义属性:Illuminate\Database\Query\Builder::$map

dd($this)在资源中做了什么,我得到了什么:

在此处输入图像描述

上课顺序照片:

class OrderPhoto extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

标签: phplaravellaravel-5

解决方案


TL;博士

在你的试试这个OrderResource

use OrderPhoto as OrderPhotoResource;

//

public function toArray($request)
{
    return [
        "id" => $this->Id,
        "photo" => new OrderPhotoResource($this->whenLoaded('OrderPhoto')),
    ];
}

解释

如您所见,您已经将 定义OrderPhoto为资源集合:

class OrderPhoto extends ResourceCollection // <-- note the extended class

所以在这种情况下,您需要使用这个类来实例化它并将集合传递给它,而不是使用静态方法collection

当您为单个对象定义 API 资源时,如下所示:

php artisan make:resource PostResource

你像下面这样使用它:

$post = Post::find(1);

return new PostResource($post);

如果您想使用API 资源来格式化资源集合而不是单个资源,则需要执行以下操作:

$posts = Post::all();

return PostResource::collection($posts); // <-- note the ::collection part

控制元数据

如果您想完全控制响应中返回的元数据,请改为定义自定义API 资源集合类。

将类生成为集合(在末尾添加“集合”或使用标志--collection):

php artisan make:resource PostResourceCollection

然后,自定义后:

$posts = Post::all();

return new PostResourceCollection($posts); // <-- instantiating the class

推荐阅读