Laravel 8 Livewire多选表单数据存入多对多关联ServClinic表问题咨询
现有代码前置修复
先修正你代码里的几处错误,否则关联逻辑无法正常运行:
- 所有模型里的
$tabel拼写错误,修正为Laravel规定的$table - 迁移文件里服务外键命名为
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
相关产品推荐
相关产品推荐

