Laravel 7使用laravel-excel导入Excel时如何正确设置关联表外键?
解决方案
核心思路
通过给导入类添加构造函数的方式,把控制器中刚保存完成的主表ID直接传递到导入类内部使用,不需要再查询数据库获取主表ID。
第一步:修改导入类 BookedVoucherDetailImport.php
<?php namespace App\Imports; use App\Model\BookedVoucherDetail; use Maatwebsite\Excel\Concerns\ToModel; use Maatwebsite\Excel\Concerns\WithStartRow; class BookedVoucherDetailImport implements ToModel, WithStartRow { // 新增私有属性存储主表ID protected $bookedVoucherId; // 新增构造方法接收主表ID public function __construct($bookedVoucherId) { $this->bookedVoucherId = $bookedVoucherId; } /** * @return int */ public function startRow(): int { return 2; } /** * @param array $row * * @return \Illuminate\Database\Eloquent\Model|null */ public function model(array $row) { return new BookedVoucherDetail([ // 直接使用传入的主表ID 'booked_voucher_id' => $this->bookedVoucherId, 'course_code' => $row[0], 'voucher_code' => $row[1], 'user_name' => $row[2], 'status' => 'OK' ]); } }
第二步:修改控制器中导入调用代码
找到控制器中Excel::import那一行,实例化导入类时传入刚保存的主表ID:
if ($data->save()) { // 把主表ID作为参数传入导入类构造方法 Excel::import(new BookedVoucherDetailImport($data->id), $request->file('file')); }
可选优化:添加事务保证数据一致性
如果担心导入过程中出错导致主表已保存但明细缺失的问题,可以用数据库事务包裹整个操作:
use DB; public function import(Request $request) { $validator = Validator::make($request->all(), [ 'file' => 'required|mimes:csv,xlx,xls,xlsx' ]); if ($validator->fails()) { return back()->with('toast_error', $validator->messages()->all()[0])->withInput(); } DB::beginTransaction(); try { $data = new BookedVoucher(); $data->name = $request->name; $fileName = time().'_'.$request->file->getClientOriginalName(); $filePath = $request->file('file')->storeAs('reports', $fileName, 'public'); $data->file = $filePath; $data->created_by = \Auth::user()->id; $data->save(); Excel::import(new BookedVoucherDetailImport($data->id), $request->file('file')); DB::commit(); return redirect()->back()->with('success','数据导入成功'); } catch (\Exception $e) { DB::rollBack(); return back()->with('toast_error', '导入失败:'.$e->getMessage())->withInput(); } }
内容的提问来源于stack exchange,提问作者Hilmi
相关产品推荐
相关产品推荐

