You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用morpToMany关联Movie与Cast时出现字段不存在错误

Laravel多态关联报错:SQLSTATE[42S22] 找不到movie_casts.movie_casts_id列

问题重现

尝试用morphToMany关联Movie和Cast模型时触发错误:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'movie_casts.movie_casts_id' in 'field list'

相关代码如下:

Movie模型

public function casts()
{
    return $this->morphToMany(Cast::class, 'movie_casts');
}

Cast模型

public function movies()
{
    return $this->morphToMany(Movie::class, 'movie_casts');
}

MovieCast模型

public function movies()
{
    return $this->morphedByMany(Movie::class, 'movie_casts');
}

public function casts()
{
    return $this->morphedByMany(Cast::class, 'movie_casts');
}

movie_casts表结构

$table->unsignedBigInteger('cast_id')->nullable();
$table->foreign('cast_id')->references('id')->on('casts');
$table->unsignedBigInteger('movie_id')->nullable();
$table->foreign('movie_id')->references('id')->on('movies');

控制器代码

public function moviesList()
{
    $movies = Movie::all();

    foreach($movies as $movie){
        $moviesWithCast = $movie->casts;
    };

    return response()->json(
        $moviesWithCast,
        200
    );
}

错误原因

你混淆了普通多对多关联和多态多对多关联的核心规则:

  1. 多态多对多关联要求中间表必须包含{关联名称}_id和{关联名称}_type两个字段,但你的表用的是movie_id和cast_id,完全不符合多态关联的结构要求。
  2. morphToMany的第二个参数是多态关联的标识名称(比如castable),而你传入的movie_casts是中间表名,导致框架错误地去查找movie_casts_id字段。

解决方案

情况1:使用普通多对多关联(适配当前表结构)

如果Movie和Cast只是单纯的多对多关系(不需要关联其他模型到该中间表),直接改用belongsToMany即可:

  • 修改Movie模型:
public function casts()
{
    return $this->belongsToMany(Cast::class, 'movie_casts');
}
  • 修改Cast模型:
public function movies()
{
    return $this->belongsToMany(Movie::class, 'movie_casts');
}
  • 删除MovieCast模型(普通多对多无需中间表模型,除非需要处理额外字段逻辑)

情况2:改用标准多态多对多关联(需扩展关联能力)

如果需要让其他模型(比如TvShow)也关联Cast,需调整表结构和模型:

  1. 修改中间表结构(新建或迁移):
$table->unsignedBigInteger('cast_id');
$table->foreign('cast_id')->references('id')->on('casts');
// 多态核心字段
$table->unsignedBigInteger('castable_id');
$table->string('castable_type');
// 复合主键
$table->primary(['cast_id', 'castable_id', 'castable_type']);
  1. 修改Movie模型:
public function casts()
{
    return $this->morphToMany(Cast::class, 'castable', 'castables');
}
  1. 修改Cast模型:
public function movies()
{
    return $this->morphedByMany(Movie::class, 'castable', 'castables');
}
  1. 中间表模型(Castable):
public function castable()
{
    return $this->morphTo();
}

public function cast()
{
    return $this->belongsTo(Cast::class);
}

控制器代码优化

原控制器代码中循环会覆盖moviesWithCast变量,最后仅返回最后一条数据,建议改用预加载避免N+1查询:

public function moviesList()
{
    $movies = Movie::with('casts')->get();
    return response()->json($movies, 200);
}

内容的提问来源于stack exchange,提问作者user20597340

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:01:12