在 Laravel API 资源响应中包含关系

Men*_*ena 3 php laravel laravel-5.7

我的目标是创建一个具有评级关系的书店 API 端点。Book & Rating的关系是这样的:

书型

/**
* a book has many ratings
*/
public function ratings()
{
    return $this->hasMany(Rating::class, 'book_id')->orderBy('created_at', 'ASC');
}
Run Code Online (Sandbox Code Playgroud)

评级模型

/**
* a rating belongs to a book
*/
public function book()
{
    return $this->belongsTo(Book::class);
}
Run Code Online (Sandbox Code Playgroud)

我的 BookResource 看起来像这样

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

use App\Http\Resources\RatingResource;

class BookResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        // return parent::toArray($request);
        return [
            'id'        => $this->id,
            'title'     => $this->title,
            'author'    => $this->author,
            'rating'    => RatingResource::collection($this->whenLoaded('ratings'))
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

我的 RatingResource 看起来像这样:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class RatingResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想获得所有书籍以及个人评级,并使用 api.php 文件中的以下两条路线获得一本书及其评级:

Route::get('/books', function() {
    return BookResource::collection(Book::all());
});

Route::get('books/{book}', function(Book $book) {
    return new BookResource($book);
});
Run Code Online (Sandbox Code Playgroud)

当我向http://12.0.0.1:8000/api/books邮递员发出获取请求时,我获取了所有书籍,但未加载评级。当我向 发出 get 请求时http://12.0.0.1:8000/api/books/1,也会发生同样的事情,返回的书没有评分。

如何基于 v5.7文档加载关系

小智 11

您应该 make: Book::with('ratings')->get();对于/books端点和 $book->load('ratings');on /books/{book}

或者,如果您想始终加载关系,请在 Book 模型中定义: protected $with = ['ratings'];

有关更多信息,请查看 Laravel 文档:https ://laravel.com/docs/5.7/eloquent-relationships#eager-loading


Rom*_*rik 6

尝试使用

class BookResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            ...
            'rating'    => RatingResource::collection($this->ratings)
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

或者如果你想使用whenLoaded

return BookResource::collection(Book::with('ratings')->get());
Run Code Online (Sandbox Code Playgroud)