Обновление отношений "Много-ко-многим" с использованием Laravel Form Model Binding & Checkboxes

У меня есть 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: Как только я проверю флажки и нажимаю submit, как мне обновить отношения? $door->colors()->detach();, чтобы очистить все существующие для этой двери, а затем $door->colors()->attach($color_id_array); для создания новых на основе массива идентификаторов цвета?

Любой ввод оценивается!

Ответ 1

Вопрос 1: Вы должны передать это в представление, которое содержит вашу форму, хотя оно также может идти прямо в представлении, хотя это не самая лучшая практика. Сделайте что-то похожее на это...

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

... где дверь, которую вы находите, - это дверь, которая обновляется. Затем перед тем, как вы вывести флажок в цикле, добавьте

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

Затем вы измените

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

to

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

Вопрос 2. На самом деле для вас существует идеальный метод. Используйте

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

Он удалит старые и добавит все новые за один снимок.

Ответ 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();