Laravel 中外键不会自动赋值,需显式设置或通过关联方法创建。确保外键字段存在、可写、类型匹配,并在 $fillable 中声明;推荐用 $user->posts()->create() 自动注入外键值。

外键不会自动赋值,是因为 Laravel 的 save() 方法只负责把当前模型存入数据库,它不会主动去“猜”或“补全”关联字段——尤其是外键。你得明确告诉它该填什么值。
确认外键字段是否真实存在且可写
先检查数据库迁移里有没有正确定义外键字段(比如 user_id 或 author_id),并且这个字段在模型的 $fillable 数组中已声明。如果字段不在 $fillable 里,save() 或 create() 都会忽略它。
- 确保迁移用了
foreignId('author_id')->constrained()或至少unsignedBigInteger('author_id') - 检查模型中
protected $fillable = ['title', 'content', 'author_id']; - 如果用的是 UUID 主键,外键字段类型也得是
uuid,否则类型不匹配会导致静默失败
别依赖 save() 自动推导,显式赋值外键
save() 不会自动从关联模型读取 ID 并填到当前模型的外键字段上。你必须手动设置。
- 错误写法:
$post = new Post; $post->user()->associate($user); $post->save();—— 这只设置了关联关系,但没改user_id字段值,除非你调用$post->user()->associate($user)后再save(),它才会把$user->id写进user_id - 正确写法:
$post = new Post(['title' => 'xxx', 'author_id' => $user->id]); $post->save(); - 或者更稳妥:
$post = new Post; $post->author_id = $user->id; $post->save();
用关联方法创建(推荐)
比起手动设外键,直接用父模型的 hasMany 关系来创建子模型,Eloquent 会自动注入外键值。
- 前提是 User 模型里有:
public function posts() { return $this->hasMany(Post::class, 'author_id'); } - 然后这样写:
$user->posts()->create(['title' => 'Hello']);—— 它会自动把$user->id填进author_id - 如果外键不是
author_id,而是user_group_id,那两边(hasMany和belongsTo)都得显式传参,否则无效
表单提交时漏传外键字段
常见问题是前端用了复选框(name="roles[]")却想存单个外键,导致后端收不到 user_group_id 值。
- 一对多场景下,外键是单值,表单必须用
<select name="user_group_id">或<input type="radio"> - 控制器里不能直接
User::create($request->all()),要先验证并确保user_group_id在请求数据中 - 验证规则加上:
'user_group_id' => 'required|exists:user_groups,id'


















