Laravel5.8.35创建菜品时出现SQLSTATE[23000]非空约束违反错误
看起来你遇到的核心问题是表单提交的餐厅ID字段名和控制器里获取的字段不匹配,导致user_id没有被正确赋值,触发了非空约束错误。我们一步步来修复:
1. 修正表单的select字段名
你的表单里select的name是Restaurant,但在DishController的store方法里,你尝试获取$request->user——这两个名字完全不一致!POST数据里显示的是Restaurant="7",但控制器根本拿不到这个值,所以$dish->user_id就成了空值。
把表单里的select name改成user(或者更语义化的user_id,记得后面控制器也要对应调整):
<p><select name="user"> @foreach ($users as $user) @if ($user->role == 'restaurant') <option value="{{$user->id}}" selected="selected">{{$user->name}}</option> @endif @endforeach </select></p>
2. 修正验证规则里的表名
Laravel默认的表名是复数形式,你的验证规则里写的是exists:user,id,但用户表实际应该是users,所以要改成:
$this->validate($request, [ 'name' => 'required|max:255', 'price' => 'required|integer|min:1', 'user' => 'exists:users,id' // 这里把user改成users ]);
3. 清理重复的路由配置
你的web.php里有多个重复的Route::get('/show/{id}',这会导致后面的路由覆盖前面的,比如UserController@create会覆盖UserController@show,DishController@show又会覆盖前面的。建议调整路由,给不同的功能设置不同的路径,比如:
// 替换原来的重复show路由 Route::get('/user/show/{id}', 'UserController@show'); Route::get('/user/create/{id}', 'UserController@create'); Route::get('/dish/show/{id}', 'DishController@show');
或者更好的方式是利用资源路由的默认路径,避免手动路由冲突。
4. 额外优化:确保选中状态正确(可选)
你的表单里所有餐厅用户的option都加了selected="selected",这会导致最后一个符合条件的用户被选中,建议改成只有当前需要的用户才选中(比如如果是编辑页面的话),创建页面可以留空或者默认选中第一个:
<option value="{{$user->id}}" {{ $loop->first ? 'selected' : '' }}>{{$user->name}}</option>
做完这些修改后,提交表单时控制器就能正确获取到餐厅用户的ID,赋值给dish->user_id,就不会触发非空约束错误了。
内容的提问来源于stack exchange,提问作者Soshi

