Laravel API调用Postman报1364错误:user_id字段无默认值
测试Laravel项目的POST接口 http://127.0.0.1:8000/api/posts/ 时,出现以下错误:
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error:
1364 Field 'user_id' doesn't have a default value
(Connection: mysql, SQL: insert intoposts(post,updated_at,created_at) values (Bruhhhh, 2024-05-25 12:35:55, 2024-05-25
12:35:55)) in file
C:\Users\Bence\Downloads\backend\vendor\laravel\framework\src\Illuminate\Database\Connection.php
on line 813
请求参数采用x-www-form-urlencoded格式:
- Key: post,Value: Bruhhhh
项目基础信息
项目基于Laravel搭建,用于处理用户评论与帖子,测试CRUD操作,搭建步骤:
composer create-project laravel/laravel example-appphp artisan install apiphp artisan make:model model_name -mfsc
posts表迁移代码
Schema::create('posts', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained('users'); $table->string("post"); $table->timestamps(); });
User模型关联代码
public function posts(): HasMany { return $this->hasMany(Post::class); } public function comments(): HasMany { return $this->hasMany(Comment::class); }
Post模型关联代码
public function user(): BelongsTo { return $this->belongsTo(User::class); }
Post模型$fillable配置
protected $fillable = [ 'user_id', 'post' ];
Factory示例代码
User::factory(5) ->has(Post::factory(3)) ->has(Comment::factory(3)) ->create();
PostController代码
<?php namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Http\Request; class PostController extends Controller { /** * Display a listing of the resource. */ public function index() { $posts = Post::all(); return response()->json($posts); } /** * Create a resource in storage. */ public function store(Request $request) { $post = Post::create($request->all()); return response()->json(['success' => $post->id.' has been created.']); } /** * Display the specified resource. */ public function show($id) { $post = Post::find($id); return response()->json($post); } /** * Update the specified resource in storage. */ public function update(Request $request, $id) { $post = Post::find($id); $post->update($request->all()); return response()->json($post->id . ' has been updated.'); } /** * Remove the specified resource from storage. */ public function destroy($id) { Post::destroy($id); return response()->json($id . ' has been deleted.'); } }
API路由配置
Route::resource('/posts', PostController::class);
错误原因
从错误信息和代码可以看出:
posts表的user_id字段是必填外键(通过foreignId()->constrained()定义,无默认值),数据库要求插入时必须提供该字段的值。- 当前请求只传了
post参数,没有传user_id。 - 控制器的
store方法直接使用Post::create($request->all()),没有补充user_id的值,导致数据库拒绝插入操作。
解决方案
方案1:关联登录用户创建帖子(生产环境推荐)
正常业务中,帖子属于已登录用户,因此需要通过认证获取当前用户ID:
- 添加认证中间件:修改路由,给posts接口加上Sanctum认证(先确保已安装Laravel Sanctum):
Route::resource('/posts', PostController::class)->middleware('auth:sanctum'); - 修改store方法:通过当前登录用户关联创建帖子,无需手动传user_id:
public function store(Request $request) { // 验证请求参数合法性 $validated = $request->validate([ 'post' => 'required|string|max:255', ]); // 利用用户关联创建帖子,自动填充user_id $post = $request->user()->posts()->create($validated); return response()->json(['success' => $post->id.' 已创建']); } - Postman请求配置:在请求Headers中添加认证令牌:
Authorization: Bearer {你的用户令牌}
方案2:手动传入user_id(测试/特定场景)
如果是测试场景允许手动指定用户ID:
- 修改store方法添加参数验证:
public function store(Request $request) { $validated = $request->validate([ 'user_id' => 'required|exists:users,id', // 验证user_id存在于users表 'post' => 'required|string|max:255', ]); $post = Post::create($validated); return response()->json(['success' => $post->id.' 已创建']); } - Postman请求参数补充:在
x-www-form-urlencoded中添加user_id参数,值为users表中存在的用户ID。
不推荐的临时方案(不适合生产)
给user_id字段设置默认值或允许为空,但会破坏外键关联的业务逻辑,仅用于临时测试:
修改迁移文件中的user_id定义:
// 方案A:设置默认值(比如默认关联ID为1的用户) $table->foreignId('user_id')->constrained('users')->default(1); // 方案B:允许为空 $table->foreignId('user_id')->nullable()->constrained('users');
修改后需要重新执行迁移:php artisan migrate:refresh(注意会清空现有数据)
内容的提问来源于stack exchange,提问作者ThereIsHope

