Laravel 5.5 HasMany关联返回所有模型而非关联模型问题
Laravel 5.5 一对多关联返回全部数据的问题排查与解决
最近在Laravel 5.5里遇到了个关联模型的坑,折腾半天终于搞定了,分享出来给有同样问题的朋友参考:
问题场景
我定义了两个关联模型:
Movie 模型
class Movie extends Model { public function comments(){ return $this->hasMany(Comment::class); } }
Comment 模型
class Comment extends Model { public function movie(){ return $this->belongsTo(Movie::class); } }
我有一个$movie实例,它的主键是字符串格式的"tt5726616":
id: "tt5726616", title: "Call Me by Your Name", original_title: "Call Me by Your Name", rate: 4, year: 2017, length: "132", language: "English, Italian, French, German", country: "Italy, France, Brazil, USA", director: "Luca Guadagnino", created_at: "2018-01-21 15:28:31", updated_at: "2018-01-21 15:28:31"
数据库里总共有4条评论,其中只有2条属于这个电影(movie_id为"tt5726616"),另外2条属于其他电影:
all: [ App\Comment {#788 id: 1, movie_id: "tt3967856", author: "user1", comment: "cool!", rate: 2, created_at: "2018-01-21 15:28:32", updated_at: "2018-01-21 15:28:32", }, App\Comment {#786 id: 2, movie_id: "tt3967856", author: "user2", comment: "not bad!", rate: 3, created_at: "2018-01-21 15:28:32", updated_at: "2018-01-21 15:28:32", }, App\Comment {#785 id: 3, movie_id: "tt5726616", author: "user1", comment: "cool!", rate: 4, created_at: "2018-01-21 15:28:32", updated_at: "2018-01-21 15:28:32", }, App\Comment {#784 id: 4, movie_id: "tt5726616", author: "user2", comment: "not bad!", rate: 5, created_at: "2018-01-21 15:28:32", updated_at: "2018-01-21 15:28:32", }, ]
奇怪的现象
当我调用$movie->comments时,本以为只会返回属于该电影的2条评论,结果却返回了全部4条,完全不符合预期。
解决方法
经过一番排查,发现问题根源在于主键和外键的数据类型:我给Movie的id和Comment的movie_id都用了字符串类型(比如"tt5726616"这种格式)。
把它们改成整数类型(比如用1、2...这类数字作为主键和外键)之后,关联查询立刻恢复正常,$movie->comments正确返回了对应的2条评论。
额外补充
如果你的业务场景确实需要用字符串作为主键,也可以通过配置模型来解决:
- 在Movie模型中明确指定主键类型和非自增:
protected $keyType = 'string'; public $incrementing = false;
- 同时在Comment模型的关联里明确指定外键和关联主键:
public function movie(){ return $this->belongsTo(Movie::class, 'movie_id', 'id'); }
不过在我的场景里,直接改成整数主键是最快捷的解决方案。
内容的提问来源于stack exchange,提问作者Marzie Tajik
相关产品推荐
相关产品推荐

