如何在Laravel Backpack中使用可重复字段添加多个手机号与地址
你需要按以下步骤调整即可实现需求:
步骤1:配置正确的模型关联
首先确保3个表对应模型的关联关系正确配置:
Person模型(app/Models/Person.php)
class Person extends Model { // 主表允许批量赋值的字段,比如人员姓名 protected $fillable = ['name']; // 一对多关联手机号表 public function phones() { return $this->hasMany(Phone::class); } // 一对多关联地址表 public function addresses() { return $this->hasMany(Address::class); } }
Phone模型(app/Models/Phone.php)
class Phone extends Model { // 子表允许批量赋值的字段 protected $fillable = ['person_id', 'landline']; // 反向关联人员表 public function person() { return $this->belongsTo(Person::class); } }
Address模型(app/Models/Address.php)
class Address extends Model { // 子表允许批量赋值的字段 protected $fillable = ['person_id', 'region_id', 'city_id', 'location_pin']; // 反向关联人员表 public function person() { return $this->belongsTo(Person::class); } // 可选:关联地区、城市表 public function region() { return $this->belongsTo(Region::class); } public function city() { return $this->belongsTo(City::class); } }
步骤2:调整CRUD字段配置
修改后的字段代码如下,核心调整点:
- 字段
name必须和模型的关联方法名完全对应 - 新增
store_as_json => false,关闭默认将数据存为主表JSON字段的逻辑 - 新增
model、relation_type参数指定关联信息 - 移除地址字段多余的
pivot => true配置(仅多对多关联需要该配置) - 新增
default回调实现编辑页自动加载已有数据 - 补全region字段的
model参数避免下拉选项加载失败
// 手机号可重复字段 $this->crud->addField([ 'name' => 'phones', // 和Person模型的关联方法名完全一致 'label' => '手机号', 'type' => 'repeatable', 'store_as_json' => false, 'model' => \App\Models\Phone::class, 'relation_type' => 'hasMany', 'fields' => [ [ 'name' => 'landline', // 对应phone表的号码存储字段 'type' => 'text', 'label' => '手机号', 'wrapper' => ['class' => 'form-group col-md-12'], ], ], 'new_item_label' => '+ 添加手机号', // 编辑页自动加载已有数据 'default' => function($entry) { return $entry->phones ?? []; } ]); // 地址可重复字段 $this->crud->addField([ 'name' => 'addresses', // 和Person模型的关联方法名完全一致 'label' => '地址', 'type' => 'repeatable', 'store_as_json' => false, 'model' => \App\Models\Address::class, 'relation_type' => 'hasMany', 'fields' => [ [ 'label' => '省份', 'type' => 'select', 'name' => 'region_id', 'attribute' =>'region', 'entity' => 'region', 'model' => \App\Models\Region::class, // 补全地区表模型路径 'wrapper' => [ 'class' => 'form-group col-md-4' ], ], [ 'label' => '城市/区', 'type' => 'select', 'name' => 'city_id', 'attribute' =>'city', 'entity' => 'city', 'allows_null' => true, 'model' => \App\Models\City::class, 'wrapper' => [ 'class' => 'form-group col-md-4' ], ], [ 'name' => 'location_pin', 'type'=> 'address_algolia', 'label' => "定位地址", 'wrapper' => [ 'class' => 'form-group col-md-4' ], ], ], 'new_item_label' => '+ 添加地址', // 编辑页自动加载已有数据 'default' => function($entry) { return $entry->addresses ?? []; } ]);
步骤3:(旧版本Backpack可选)手动处理存储逻辑
如果你使用的Backpack版本低于5.4,自动关联存储不生效,可以在PersonCrudController中添加以下方法手动处理数据:
// 新增数据时保存关联 public function store() { $this->crud->hasAccessOrFail('create'); $response = $this->crud->store(); $person = $this->crud->getCurrentEntry(); // 保存手机号 $phones = request()->input('phones', []); $person->phones()->delete(); foreach ($phones as $phone) { $person->phones()->create($phone); } // 保存地址 $addresses = request()->input('addresses', []); $person->addresses()->delete(); foreach ($addresses as $address) { $person->addresses()->create($address); } return $response; } // 更新数据时同步关联 public function update() { $this->crud->hasAccessOrFail('update'); $response = $this->crud->update(); $person = $this->crud->getCurrentEntry(); // 同步手机号 $phones = request()->input('phones', []); $person->phones()->delete(); foreach ($phones as $phone) { $person->phones()->create($phone); } // 同步地址 $addresses = request()->input('addresses', []); $person->addresses()->delete(); foreach ($addresses as $address) { $person->addresses()->create($address); } return $response; }
内容的提问来源于stack exchange,提问作者Haymanot Brhane
相关产品推荐
相关产品推荐

