Laravel多Action Owner编辑表单的分组与动态更新实现
问题描述
在我的Laravel应用中,原有actions数据表(实际代码中使用audit_observation_details表),此前每个动作仅对应一个所有者,现在需要支持单个动作分配多个所有者。
目前已完成创建功能:给表单的select标签添加multiple属性,控制器通过循环为每个选中的所有者创建一条记录,同属一个动作的所有记录通过action_group_id(UUID)分组标识。
现在需要实现编辑功能,要求:
- 编辑表单支持再次选择多个动作所有者
- 提交时保留选中的所有者记录,删除取消选中的对应记录
- 更新动作的公共数据(如
action_title),同时为新选中的所有者创建新记录
现有代码
前端创建表单代码
<div class="form-group"> <label for="action-owner" class="text-bold">Action Owner</label> <select multiple="multiple" name="action_owners[]" class="form-control select2" id="action-owner"> </select> </div>
创建动作控制器代码
public function add_observation() { try { DB::beginTransaction(); $action_title = $_POST['action_title']; $group_uid = Str::uuid(); foreach ($_POST['action_owners'] as $action_owner_id) { $ObjDetails = new ObservationDetails; $ObjDetails->action_title = $action_title; $ObjDetails->action_owner = $action_owner_id; $ObjDetails->action_group_id = $group_uid; $ObjDetails->save(); } DB::commit(); echo ('Successful. An email will be sent soon.'); } catch (Exception $e) { DB::rollBack(); echo ('Create Action Not Successful'); } }
表结构更新代码
Schema::table('audit_observation_details', function (Blueprint $table) { $table->uuid('action_group_id')->nullable()->after('action_owner'); });
编辑功能实现方案
1. 编辑表单回显处理
首先在编辑页面加载时,根据action_group_id获取动作的现有所有者,设置select标签的选中状态。
控制器编辑方法
public function edit($action_group_id) { // 获取动作基础信息(同组记录的公共字段一致,取第一条即可) $action = ObservationDetails::where('action_group_id', $action_group_id)->first(); // 获取该动作的所有所有者ID数组 $selectedOwners = ObservationDetails::where('action_group_id', $action_group_id)->pluck('action_owner')->toArray(); // 假设从用户表获取所有可选所有者 $users = User::all(); return view('actions.edit', compact('action', 'selectedOwners', 'action_group_id', 'users')); }
前端编辑表单
<div class="form-group"> <label for="action-owner" class="text-bold">动作所有者</label> <select multiple="multiple" name="action_owners[]" class="form-control select2" id="action-owner"> @foreach($users as $user) <option value="{{ $user->id }}" {{ in_array($user->id, $selectedOwners) ? 'selected' : '' }}> {{ $user->name }} </option> @endforeach </select> <!-- 隐藏字段传递动作组ID --> <input type="hidden" name="action_group_id" value="{{ $action_group_id }}"> </div> <!-- 动作标题等公共字段 --> <div class="form-group"> <label for="action-title">动作标题</label> <input type="text" name="action_title" class="form-control" value="{{ $action->action_title }}"> </div>
2. 控制器更新逻辑
使用事务保证数据一致性,完成「更新公共字段、删除取消的所有者记录、新增选中的新所有者记录」三个操作:
public function update(Request $request) { // 可选:添加请求验证 $request->validate([ 'action_group_id' => 'required|uuid', 'action_title' => 'required|string|max:255', 'action_owners' => 'required|array', 'action_owners.*' => 'exists:users,id' // 校验所有者ID存在于用户表 ]); try { DB::beginTransaction(); $actionGroupId = $request->action_group_id; $newActionTitle = $request->action_title; $newOwnerIds = $request->action_owners; // 1. 获取当前动作组的所有所有者记录 $currentRecords = ObservationDetails::where('action_group_id', $actionGroupId)->get(); $currentOwnerIds = $currentRecords->pluck('action_owner')->toArray(); // 2. 更新所有同组记录的公共字段 ObservationDetails::where('action_group_id', $actionGroupId)->update([ 'action_title' => $newActionTitle ]); // 3. 删除取消选中的所有者记录 $ownersToDelete = array_diff($currentOwnerIds, $newOwnerIds); if (!empty($ownersToDelete)) { ObservationDetails::where('action_group_id', $actionGroupId) ->whereIn('action_owner', $ownersToDelete) ->delete(); } // 4. 新增新选中的所有者记录 $ownersToAdd = array_diff($newOwnerIds, $currentOwnerIds); foreach ($ownersToAdd as $ownerId) { $newRecord = new ObservationDetails(); $newRecord->action_title = $newActionTitle; $newRecord->action_owner = $ownerId; $newRecord->action_group_id = $actionGroupId; $newRecord->save(); } DB::commit(); return redirect()->back()->with('success', '动作更新成功,邮件将稍后发送。'); } catch (Exception $e) { DB::rollBack(); return redirect()->back()->with('error', '动作更新失败'); } }
3. 路由配置
添加编辑和更新的路由:
Route::get('/actions/edit/{action_group_id}', [ActionController::class, 'edit'])->name('actions.edit'); Route::post('/actions/update', [ActionController::class, 'update'])->name('actions.update');
注意事项
- 确保
ObservationDetails模型中声明可填充字段:
class ObservationDetails extends Model { protected $fillable = ['action_title', 'action_owner', 'action_group_id']; }
内容的提问来源于stack exchange,提问作者Pavel Rahman
相关产品推荐
相关产品推荐

