在 Laravel API 资源响应中包含关系
Including relationships in Laravel API resource response
我的目标是创建一个具有评级关系的书店 API 端点。 Book & Rating 的关系是这样的:
图书模型
/**
* 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
尝试使用
class BookResource extends JsonResource
{
public function toArray($request)
{
return [
...
'rating' => RatingResource::collection($this->ratings)
];
}
}
或者如果您想使用 whenLoaded
return BookResource::collection(Book::with('ratings')->get());
正如@honarkhah 向我指出的那样,我在获取 books
或 book
时省略了加载 ratings
,所以我通过在获取时添加 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'));
});
你应该:
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
我的目标是创建一个具有评级关系的书店 API 端点。 Book & Rating 的关系是这样的:
图书模型
/**
* 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
尝试使用
class BookResource extends JsonResource
{
public function toArray($request)
{
return [
...
'rating' => RatingResource::collection($this->ratings)
];
}
}
或者如果您想使用 whenLoaded
return BookResource::collection(Book::with('ratings')->get());
正如@honarkhah 向我指出的那样,我在获取 books
或 book
时省略了加载 ratings
,所以我通过在获取时添加 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'));
});
你应该:
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