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

时间:2013-11-24 18:55:18

标签: php laravel laravel-4 eloquent blade

我有3张桌子:

  • ID
  • 名称
  • 图像

颜色

  • ID
  • 名称
  • 图像

door_colors

  • ID
  • 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');
    }
}

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

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

管理员表单视图

{{ 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数组创建新门?

感谢任何输入!

2 个答案:

答案 0 :(得分:20)

问题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'));

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

答案 1 :(得分:2)

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

在您的控制器编辑中,

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

如果您使用select,则在模板中

{{ 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();