Many-to-Many Eloquent relationship update with Laravel Form Model Binding & Checkboxes

亡梦爱人 提交于 2019-12-04 17:11:37

问题


I have 3 tables:

doors

  • id
  • name
  • image

colors

  • id
  • name
  • image

door_colors

  • id
  • door_id
  • color_id

and 2 models with a many-to-many relationship (each door comes in a variety colors, and many colors overlap door-to-door):

Door Model

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

Color Model

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

I want to create a form where I can edit the door, and update the available colors via checkboxes. This is my Admin Doors Controller

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

and the Admin Doors Form View

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

Question 1: How do I make it so that as the checkboxes are outputted, the ones with an existing relationship with the current door are checked and the ones without are unchecked.

Question 2: Once I check the boxes and hit submit, how would I update the relationships? $door->colors()->detach(); to clear all existing ones for this door, then $door->colors()->attach($color_id_array); to create new ones based on an array of color ids?

Any input is appreciated!


回答1:


Question 1: You should pass this into the view that contains your form, though it can also go right in the view, though that's not really best practice. Do something similar to this...

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

...where the door you are finding is the door that's being updated. Then before you output the checkbox in the loop, add

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

Then you would change

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

to

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

Question 2: There is actually a perfect method given to you for this. Use

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

It will both delete the old ones and add all the new ones in one shot.




回答2:


Suppose you are modeling user and role and want to edit user with roles.

In your controller edit,

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

In your template if you use select,

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

In your controller update,

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

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


来源:https://stackoverflow.com/questions/20179473/many-to-many-eloquent-relationship-update-with-laravel-form-model-binding-chec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!