使用 Laravel 表单模型绑定和复选框更新多对多 Eloquent 关系

Posted

技术标签:

【中文标题】使用 Laravel 表单模型绑定和复选框更新多对多 Eloquent 关系【英文标题】:Many-to-Many Eloquent relationship update with Laravel Form Model Binding & Checkboxes 【发布时间】:2013-12-09 09:02:00 【问题描述】:

我有 3 张桌子:

身份证 姓名 图片

颜色

身份证 姓名 图片

door_colors

身份证 door_id color_id

和2个多对多关系的模型(每扇门都有多种颜色,而且很多颜色门对门重叠):

门模型

class Door extends Eloquent 
    public function colors()
    
        return $this->belongsToMany('Color', 'door_colors');
    

颜色模型

class Color extends Eloquent 
    public function doors()
    
        return $this->belongsToMany('Door', 'door_colors');
    

我想创建一个表单,我可以在其中编辑门,并通过复选框更新可用颜色。 这是我的 Admin Doors 控制器

class AdminDoorsController extends AdminController 
    public function edit($id)
    
        $data['door'] = Door::find($id);
        $data['colors'] = Color::all();
        return View::make('admin/doors/form', $data);
    

Admin Doors 表单视图

 Form::model($door) 
Colors:
@foreach ($colors as $color)
 Form::checkbox('colors[]', $color->id)   $color->name 
@endforeach
 Form::close() 

问题1:我如何做到这样在输出复选框时,与当前门存在关系的那些被选中,而没有关系的则被取消选中。

问题 2:选中复选框并点击提交后,我将如何更新关系? $door->colors()->detach(); 清除此门的所有现有门,然后$door->colors()->attach($color_id_array); 根据一组颜色 ID 创建新门?

感谢任何输入!

【问题讨论】:

【参考方案1】:

问题 1:您应该将其传递到包含您的表单的视图中,尽管它也可以直接在视图中传递,但这并不是真正的最佳实践。做类似的事情......

$checkeds = Door::find(1)->colors()->lists('id');

...您找到的门是正在更新的门。然后在循环中输出复选框之前,添加

$checked = in_array($color->id, $checkeds) ? true : false;

那么你会改变

 Form::checkbox('colors[]', $color->id)  
 $color->name ` 

 Form::checkbox('colors[]', $color->id, $checked) 
 $color->name 

问题2:其实有一个完美的方法给了你。使用

$door->colors()->sync(Input::get('colors'));

它会一次性删除旧的并添加所有新的。

【讨论】:

很好的解决方案!通过简单的修改,在 Laravel 5.1 中就像一个魅力一样工作。 lists 方法已替换为 pluck。这个解决方案效果很好,谢谢!【参考方案2】:

假设您正在为用户和角色建模,并希望使用角色编辑用户。

在您的控制器编辑中,

$user = User::find($id);
$roles = Role::lists('name', 'id'); // to populate all roles

如果您使用选择,则在您的模板中,

 Form::select('roles[]', $roles, array_pluck($user->roles, 'id'), ['multiple']) 

在您的控制器更新中,

$inputs = Input::all();
$roles = $inputs['roles'];
$user->roles()->sync($roles);

// $user->fill($inputs);
// $user->save();

【讨论】:

以上是关于使用 Laravel 表单模型绑定和复选框更新多对多 Eloquent 关系的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel 中多个复选框的 attach() 更新多对多关系数据

Laravel:重复字段(和字段组):表单模型绑定

如何在模型绑定中使用带有 Laravel 的复选框组

laravel 表单模型绑定 - 日期格式

Django:ModelForm 使用自定义查询预填充复选框

Laravel 表单模型绑定