Laravel REST API获取电影所属全部体裁的实现方法
问题原因
你之前代码报错的核心原因是方法用错了:
with()是Eloquent查询构造器的预加载方法,仅适用于还未执行查询的构造器场景,比如Movie::with('genres')->first()- 路由模型绑定注入的
$movie已经是查询完成的单个Movie模型实例,此时调用$movie->with('genres')会返回未执行的查询构造器对象,不是模型实例,所以Resource访问id属性时会抛出不存在的错误。
实现步骤
1. 修改控制器show方法
对已经查询出的模型实例,要用load()方法懒加载关联,替换原有代码即可:
public function show(Movie $movie) { // load()在现有模型实例上加载关联,返回的仍是模型实例 return new MovieResource($movie->load('genres')); }
2. 修改MovieResource,添加体裁字段
在toArray方法中新增genres字段,用你已经写好的GenreResource做格式化,同时用whenLoaded避免无意义的额外查询:
public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'status' => $this->status, 'image_path' => url()->to('/images/' .$this->image_path), // 新增:仅当genres关联被加载时,返回格式化后的体裁数据 'genres' => GenreResource::collection($this->whenLoaded('genres')), ]; }
注意:需要在MovieResource文件顶部引入GenreResource类,即添加
use App\Http\Resources\GenreResource;,否则会报类不存在错误。
最终效果
改完后访问对应接口,返回结构示例如下:
{ "data": { "id": 1, "name": "测试电影", "status": 1, "image_path": "http://127.0.0.1:8000/images/default.png", "genres": [ { "id": 1, "name": "科幻" }, { "id": 3, "name": "动作" } ] } }
你之前定义的模型多对多关联、迁移、GenreResource代码都是正确的,不需要额外修改。
内容的提问来源于stack exchange,提问作者Illia
相关产品推荐
相关产品推荐

