Laravel中更新Video模型video_metadata字段第二种方法失效求助
Laravel模型实例更新JSON嵌套字段无效的原因及解决方案
原因分析
两种方法的核心差异在于执行逻辑的不同:
- 第一种用查询构造器的
update方法,会直接将video_metadata->author_id解析为SQL层面的JSON字段更新语法(比如MySQL的JSON_SET),完全绕开了Laravel模型的属性赋值、填充校验等逻辑,只要数据库字段存在就能生效。 - 第二种用模型实例的
update方法,Laravel会先尝试将数组中的键映射为模型的直接属性,但video_metadata->author_id并不是模型的直接属性——模型只会把video_metadata当作一个整体属性处理。如果你的Video模型没有正确配置$fillable或$casts,模型就无法识别这种嵌套的点语法更新,导致操作无效。
解决方案
根据你的场景,有两种可靠的解决方式:
方案1:直接修改嵌套属性后保存
先取出video_metadata的数组值,修改指定键后重新赋值保存:
$metadata = $this->video->video_metadata; $metadata['author_id'] = 2; $this->video->video_metadata = $metadata; $this->video->save();
方案2:配置模型后使用更简洁的写法
首先在Video模型中完成两个关键配置:
// 确保video_metadata字段允许被批量赋值 protected $fillable = ['video_metadata']; // 将JSON字段自动转换为数组处理 protected $casts = [ 'video_metadata' => 'array', ];
配置完成后,你可以选择两种简洁的更新方式:
- 直接修改嵌套属性后保存:
$this->video->video_metadata['author_id'] = 2; $this->video->save();
- 用
update方法传入合并后的数组:
$this->video->update([ 'video_metadata' => array_merge( $this->video->video_metadata, ['author_id' => 2] ) ]);
如果你的Laravel版本是9及以上,配置好$casts后,甚至可以直接用点语法在update中更新:
$this->video->update([ 'video_metadata->author_id' => 2 ]);
内容的提问来源于stack exchange,提问作者DragonVN
相关产品推荐
相关产品推荐

