Обновление отношений "Много-ко-многим" с использованием Laravel Form Model Binding & Checkboxes
У меня есть 3 таблицы:
двери
цвета
door_colors
и 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();