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

Laravel 8 Livewire多选表单数据存入多对多关联ServClinic表问题咨询

现有代码前置修复

先修正你代码里的几处错误,否则关联逻辑无法正常运行:

  1. 所有模型里的$tabel拼写错误,修正为Laravel规定的$table
  2. 迁移文件里服务外键命名为serve_id,和Laravel多对多默认外键规则不符,需要在关联方法里手动指定

第一步:修正模型关联代码

Clinic 模型

<?php
class Clinic extends Model
{
    use HasFactory;
    protected $table = "clinics";

    // 手动指定中间表、当前模型外键、关联模型外键
    public function services(){
        return $this->belongsToMany(ServiceData::class,'serv_clinics', 'clinic_id', 'serve_id');
    }
}

ServiceData 模型

<?php
class ServiceData extends Model
{
    use HasFactory;
    // 修正拼写错误
    protected $table = "service_data";
    
    // 关联方法名改为复数更符合多对多的语义,同时指定外键
    public function clinics(){
        return $this->belongsToMany(Clinic::class,'serv_clinics', 'serve_id', 'clinic_id');
    }
}

第二步:编写Livewire存储逻辑

你的表单用了wire:submit.prevent="storeServices",所以存储逻辑写在对应的Livewire组件里即可:

<?php
namespace App\Http\Livewire;

use App\Models\Clinic;
use App\Models\ServiceData;
use Livewire\Component;

class ClinicService extends Component
{
    // 绑定表单字段
    public $clinics = [];
    public $services = [];

    // 表单验证规则
    protected $rules = [
        'clinics' => 'required|array|min:1',
        'clinics.*' => 'exists:clinics,id',
        'services' => 'required|array|min:1',
        'services.*' => 'exists:service_data,id',
    ];

    public function storeServices()
    {
        $this->validate();

        // 遍历选中的诊所,关联选中的服务
        foreach ($this->clinics as $clinicId) {
            $clinic = Clinic::findOrFail($clinicId);
            // syncWithoutDetaching不会删除已有的关联,仅新增不存在的关联;如果要覆盖当前诊所的所有关联就用sync方法
            $clinic->services()->syncWithoutDetaching($this->services);
        }

        session()->flash('message', '诊所服务关联添加成功');
        // 提交后清空表单可选
        $this->reset(['clinics', 'services']);
    }

    public function render()
    {
        return view('livewire.clinic-service', [
            'clinics' => Clinic::all(),
            'services' => ServiceData::all(),
        ]);
    }
}

第三步:视图添加Livewire绑定

给两个下拉选择框加上wire:model属性,实现数据双向绑定:

<!-- 诊所选择框 -->
<select class="sel_categories form-control" name="clinics[]" wire:model="clinics">

<!-- 服务选择框 -->
<select class="form-control" name="services[]" multiple="multiple" wire:model="services">

后续关联数据读取方法

  • 获取单个诊所下的所有服务:
$clinic = Clinic::find(1);
$serviceList = $clinic->services;
  • 获取单个服务所属的所有诊所:
$service = ServiceData::find(1);
$clinicList = $service->clinics;

内容的提问来源于stack exchange,提问作者Ezz Elkady

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:27:02