Включение отношений в ответ ресурса API Laravel - PullRequest
0 голосов
/ 04 июня 2019

Моя цель - создать конечную точку API книжного магазина с отношениями рейтингов.Соотношение между книгой и рейтингом выглядит следующим образом:

Модель книги

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

Модель рейтинга

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

Мой 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'))
        ];
    }
}

Мой 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);
    }
}

Я хочу собрать все книги вместе с индивидуальными рейтингами и получить одну книгу вместе с ее рейтингом, а также использовать оба маршрута ниже в файле api.php

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

Route::get('books/{book}', function(Book $book) {
    return new BookResource($book);
});

Когда я делаю запрос на получение http://12.0.0.1:8000/api/books для почтальона, я получаю все книги, но рейтинги не загружаются.То же самое происходит, когда я делаю запрос на получение http://12.0.0.1:8000/api/books/1, книга возвращается без рейтинга.

Как загружаются отношения на основе v5.7 doc

Ответы [ 3 ]

2 голосов
/ 04 июня 2019

Вы должны сделать: Book::with('ratings')->get(); для конечной точки /books и $book->load('ratings'); для /books/{book}.

Или, если вы хотите всегда загружать отношения, определите в модели Book: protected $with = ['ratings'];

Для получения дополнительной информации, ознакомьтесь с документацией Laravel: https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

1 голос
/ 04 июня 2019

Попробуйте использовать

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

или если вы хотите использовать whenLoaded

return BookResource::collection(Book::with('ratings')->get());
0 голосов
/ 04 июня 2019

Как указал мне @honarkhah, я исключил загрузку ratings при извлечении books или book, поэтому я исправил это, добавив load() при извлечении данных, подобных этому

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

Route::get('books/{book}', function(Book $book) {
    return new BookResource($book->load('ratings'));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...