Laravel,Form :: select无法更新多对多的关系

时间:2014-04-28 17:44:53

标签: select laravel laravel-4 many-to-many pivot-table

我是Laravel的新手,我肯定会对此感到愚蠢,因为我已经阅读了这些文档并且我已经搜遍了谷歌,但我还是一直在搜索没有得到如何回顾这个。我在画廊和艺术家之间有M:M的关系。在每个图库编辑页面中,我有一个表单来更新工作正常的图库的名称和网址。在同一页面中,我有另外两个选择表单,一个用于将艺术家添加到图库,另一个用于删除艺术家,需要更新名为" galleries_artists"的数据透视表。我为这两种形式创建了两种自定义方法,称为" postAdd"和" postRemove"但无论我尝试什么,我都无法将它们付诸实践。 下面是我到目前为止的代码。希望有人能帮助我理解我所犯的愚蠢错误。

模特 - Artist.php

class Artist extends Eloquent {

    protected $fillable = array('name');

    public static $rules = array(
        'name'=>'required|min:2'
    );

    public function galeries() {
        return $this->belongsToMany('Gallery', 'galeries_artists', 'artist_id', 'gallery_id', 'stand_id');
    }
}

模型 - Gallery.php

class Gallery extends Eloquent {

    protected $fillable = array('name', 'stand_id', 'url');

    public static $rules = array(
        'stand_id'=>'required|integer'
    );

    public function stand() {
        return $this->belongsTo('Stand');
    }

    public function artist() {
        return $this->belongsToMany('Artist', 'galleries_artists', 'gallery_id', 'artist_id', 'stand_id');
    }

}

Controller - GalleriesController.php

public function postAdd($id, $aid) {

        $input = array_except(Input::all(), '_method');
        $v = Validator::make(Input::all(), Artist::$rules);

        if ($v->passes()) {
            $gallery = Gallery::find($id);
            $add_artist = Input::get();
            $add_artist->galleries()->attach(Input::get('add_artist'));
            $add_artist->save();

            return Redirect::route('admin.galleries.edit')
            ->with('message', 'Artist added successfully.');
        }

        return Redirect::route('admin.galleries.edit')
            ->with('message', 'Something went wrong')
            ->withErrors($v)
            ->withInput();
    }

    public function postRemove($id, $aid) {

        $input = array_except(Input::all(), '_method');
        $v = Validator::make(Input::all(), Artist::$rules);

        if ($v->passes()) {
            $gallery = Gallery::find($id);
            $remove_artist = Input::get();
            $remove_artist->galleries()->detach(Input::get('remove_artist'));
            $remove_artist->save();

            return Redirect::route('admin.galleries.edit')
            ->with('message', 'Artist removed successfully.');
        }

        return Redirect::route('admin.galleries.edit')
            ->with('message', 'Something went wrong')
            ->withErrors($v)
            ->withInput();

    }

edit.blade.php 添加表格

{{ Form::open(array('class' => '', 'method' => 'put', 'action'=> array('GalleriesController@postAdd', $gallery->id , $add_artist->id ))) }}
                                                <div class="form-group">
                                                    {{ Form::label('Add Artist:') }}
                                                    {{ Form::select('add_artist', $other_artists_name, null, array('class'=>'form-control')) }}
                                                </div>
                                                {{ Form::button('Add Artist', array('type' => 'submit', 'class'=>'btn btn-primary')) }}
                                                {{ Form::close() }}

edit.blade.php 删除表单

{{ Form::open(array('class' => '', 'method' => 'put', 'action'=>array('GalleriesController@postRemove', $id , 'aid'))) }}
                                                <div class="form-group">
                                                    {{ Form::label('Remove Artist:') }}
                                                    {{ Form::select('remove_artist', $gallery_artists_name, null, array('class'=>'form-control')) }}
                                                </div>
                                                {{ Form::button('Remove Artist', array('type' => 'submit', 'class'=>'btn btn-danger')) }}
                                                {{ Form::close() }}

routes.php文件

Route::post('admin/galleries/{galleries}/add/{aid}', 'GalleriesController@postAdd');
Route::post('admin/galleries/{galleries}/remove/{aid}', 'GalleriesController@postRemove');
Route::resource('admin/galleries', 'GalleriesController');

我对代码做了很多更改,很多事情可能会混淆不清。对不起,如果是这样的话。

1 个答案:

答案 0 :(得分:0)

你让它变得非常困难。这是我所做的,但有复选框,这使我能够减少我需要使用的函数和表单的数量。我已经跳过了验证,但我所做的事情已经过测试,似乎工作正常。

更换选择的复选框不应该是额外的工作,但我建议在这种情况下使用多选,因为再次,使用它会更简单从用户的角度来看,您更容易使用。如果必须选择,我是否应该修改我的答案。

控制器

class ArtController extends BaseController {

    public function getIndex($artist_id)
    {
        // Get our artist with associated galleries
        $artist = Artist::find($artist_id);
        $artist->load('galleries');

        // Get all galleries to populate our checkboxes
        $galleries = Gallery::all();

        // Show form
        return View::make('art.gallery_update_form')->with('artist', $artist)->with('galleries', $galleries);
    }

    public function postIndex($artist_id)
    {
        // Grab our artist
        $artist = Artist::find($artist_id);

        // Sync the galleries.  If no galleries were chosen, send it an empty array.  Sync will perform both write and delete operations for you in one shot.  Very handy.
        $artist->galleries()->sync(Input::get('galleries', array()));

        // Reshow the form
        return $this->getIndex($artist_id);
    }
}

视图

@section('content')
    {{ Form::open() }}

    <!-- Get a list of our ID's so we can check/uncheck the checkboxes as we go -->
    <?php $artist_galleries = $artist->galleries->lists('id'); ?>

    <!-- Create checkbox for each gallery -->
    @foreach($galleries as $gallery)
        {{ Form::label($gallery->id, $gallery->name) }}

        <!-- 3rd parameter is where the magic happens, it's looking in our list of galleries 
        we created a few lines up for the id to see if the artist belongs to that gallery or not -->
        {{ Form::checkbox('galleries[]', $gallery->id, in_array($gallery->id, $artist_galleries), array('id' => $gallery->id)) }}
        <br />
    @endforeach

    {{ Form::submit() }}
    {{ Form::close() }}
@stop

路线

Route::get('art/{artist_id}', array('uses' => 'ArtController@getIndex'));
Route::post('art/{artist_id}', array('uses' => 'ArtController@postIndex'));

修改

只需让您的postAdd()方法正常运行,所有应该要求的就是这样......

public function postAdd($id, $aid) 
{

    $input = array_except(Input::all(), '_method');
    $v = Validator::make(Input::all(), Artist::$rules);

    if ($v->passes()) {
        $gallery = Gallery::find($id);
        $gallery->artists()->attach($aid);

        return Redirect::route('admin.galleries.edit')
        ->with('message', 'Artist added successfully.');
    }

    return Redirect::route('admin.galleries.edit')
        ->with('message', 'Something went wrong')
        ->withErrors($v)
        ->withInput();
}

我对这个功能的目的可能有点困惑。在我写作时,它会将选定的艺术家附加到画廊。我不确定使用输入的目的。您似乎也可能尝试保存新艺术家,就好像您希望用户能够创建新艺术家并在创建艺术家时将该艺术家分配到图库中一样?如果您传入艺术家ID和图库ID,那应该是您所需要的,并且不需要Input类。

通常情况下,您只会传入您为其生成链接的图库ID,并且它将在URI中,并且艺术家将通过表单传入,在这种情况下您需要使用Input::get('add_artist'),这样可以使你的URI更加清晰。

postRemove()功能完全相同,除非您想要使用detach()。这一切都假设当然所有其他功能负责传递图库ID和艺术家ID,以及您已经在模型中设置的关系本身。