Laravel5.8报错SQLSTATE[HY000]1364 user_id无默认值如何解决
Laravel 5.8 框架执行reports表数据插入操作时抛出如下SQL异常:
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into
reports(patient_name,gender,ic,phone,current_location,status,emg_code,updated_at,created_at) values (dfd, female, sdf, sdf, sdf, sdf, sdf, 2022-06-13 05:53:11, 2022-06-13 05:53:11))
其中user_id是reports表关联Users表的外键字段。
- 数据库层面
reports.user_id字段设置为非空、无默认值,但插入数据时请求参数未携带该字段值,触发SQL必填字段校验错误。 - 关联逻辑存在多处错误:Report模型仅定义了与User的
belongsTo一对多反向关联,但assignUser方法调用了不存在的users()多对多关联方法,且关联保存方向写反,后续绑定逻辑无法正常执行。 - 控制器create方法向视图传递用户列表时,仅提取了用户名字段,丢失用户id,前端表单无法提交正确的关联用户id参数。
- store方法未对
user_id字段做必填校验,且先创建缺失user_id的Report记录、再尝试绑定用户的流程顺序错误,在绑定步骤执行前就会触发SQL报错。
结合当前表结构(reports表持有user_id外键,为一对多关联:1个用户可拥有多个报告,1个报告仅归属1个用户),按以下步骤修改代码:
1. 修正HasUser Trait关联逻辑
删除错误的多对多调用逻辑,调整用户绑定方法:
// HasUser Trait 修正后代码 public function user() { return $this->belongsTo(User::class); } public function assignUser($userId) { $this->user_id = $userId; return $this->save(); }
2. 修正控制器create方法
传递用户列表时保留用户id,供前端表单选择使用:
public function create() { // pluck第一个参数为选项显示文本,第二个为选项提交值,直接生成id=>name的键值对 $users = User::pluck('name', 'id'); return view('admin.reports.create', compact('users')); }
3. 调整创建报告的前端表单
添加关联用户选择字段,提交user_id参数:
{{-- 表单内新增用户选择项 --}} <div class="form-group"> <label>归属用户</label> <select name="user_id" class="form-control" required> <option value="">请选择用户</option> @foreach($users as $id => $name) <option value="{{ $id }}">{{ $name }}</option> @endforeach </select> </div>
4. 修正控制器store方法
添加user_id参数校验,调整创建流程,直接携带合法user_id创建报告记录:
public function store(Request $request) { $validatedData = $this->validate($request, [ // 新增user_id必填、且对应记录存在于users表的校验规则 'user_id' => 'required|exists:users,id', 'patient_name' => 'required|string', 'gender' => ['required', 'in:male,female'], 'ic' => 'required|string', 'phone' => 'required|string', 'current_location' => 'required|string', 'status' => 'required|string', 'emg_code' => 'required|string' ]); // 直接使用校验通过的数据创建报告,此时user_id已存在,不会触发字段无默认值错误 $report = Report::create($validatedData); return redirect('admin/reports')->with('flash_message', 'Report added!'); }
补充说明:如果实际业务需求为一个报告可绑定多个用户,当前表结构设计不符合多对多关联规范,需要删除reports表的user_id字段,新建report_user中间表存储报告与用户的关联关系,再定义多对多关联方法实现绑定逻辑。
内容的提问来源于stack exchange,提问作者Fiona Goi

