You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:35:56