我的目标是建立具有评级关系的书店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
发出get请求时,也会发生同样的事情,这本书没有评分就退回了。
如何基于v5.7 doc
加载关系答案 0 :(得分:2)
您应进行以下操作:
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 :(得分:1)
尝试使用
class BookResource extends JsonResource
{
public function toArray($request)
{
return [
...
'rating' => RatingResource::collection($this->ratings)
];
}
}
或者如果您想使用whenLoaded
return BookResource::collection(Book::with('ratings')->get());
答案 2 :(得分:0)
正如@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'));
});