如何在Laravel中用一个控制器函数添加一对多关联的两张表数据
实现方案
首先,需确保前端请求参数中包含学生基础信息,以及以titles数组形式传递的头衔数据,示例请求体结构如下:
{ "birth_date": "1990-01-01", "first_name": "John", "last_name": "Doe", "gender": "male", "hire_date": "2020-01-01", "titles": [ { "title": "Student", "from_date": "2020-01-01", "to_date": "2024-01-01" }, { "title": "Honor Student", "from_date": "2022-01-01", "to_date": "2024-01-01" } ] }
接着修改StudentController的addStudent方法,通过Laravel关联模型特性批量创建头衔,同时用数据库事务保证数据一致性:
use Illuminate\Support\Facades\DB; public function addStudent(Request $request) { // 可选:添加请求验证,过滤非法参数 $request->validate([ 'birth_date' => 'required|date', 'first_name' => 'required|string', 'last_name' => 'required|string', 'gender' => 'required|string', 'hire_date' => 'required|date', 'titles' => 'required|array', 'titles.*.title' => 'required|string', 'titles.*.from_date' => 'required|date', 'titles.*.to_date' => 'required|date', ]); // 开启事务,确保学生与头衔数据同时创建成功或失败 DB::beginTransaction(); try { // 创建学生,排除头衔字段避免填充报错 $student = Student::create($request->except('titles')); // 通过关联关系批量创建头衔,自动填充stu_no外键 $student->titles()->createMany($request->input('titles')); DB::commit(); // 返回包含关联头衔的完整学生数据 return response($student->load('titles'), 201); } catch (\Exception $e) { DB::rollBack(); return response(['message' => '创建失败: ' . $e->getMessage()], 500); } }
核心说明:
- 用
$request->except('titles')剥离头衔数据,只传递学生允许填充的字段到create方法,避免因字段不在fillable中报错。 - 依赖模型关联的
createMany方法,Laravel会自动将当前学生的stu_no赋值给头衔表的stu_no外键,无需手动设置。 - 数据库事务确保数据一致性,防止出现学生创建成功但头衔创建失败的异常情况。
- 可选的请求验证提前拦截非法请求,返回明确的错误提示。
- 最后用
load('titles')预加载关联的头衔数据,返回给前端完整的学生信息。
如果仅需创建单个头衔,可替换为create方法:
$student->titles()->create($request->input('title'));
内容的提问来源于stack exchange,提问作者Narakaya
相关产品推荐
相关产品推荐

