Laravel,表单::select无法更新多对多关系

Laravel,表单::select无法更新多对多关系,select,laravel,laravel-4,many-to-many,pivot-table,Select,Laravel,Laravel 4,Many To Many,Pivot Table,我是拉威尔的新手,我对这一点肯定是哑口无言的,因为我已经阅读了文档,我在谷歌上搜索了很多次,但我不知道该怎么做。我在画廊和艺术家之间有一种M:M的关系。在每个图库编辑页面中,我都有一个表单,用于更新图库的名称和url。在同一页面中,我有两个其他选择表单,一个用于向库中添加艺术家,另一个用于删除艺术家,需要更新名为库中艺术家的透视表。我为这两个表单创建了两个自定义方法,分别称为postAdd和postRemove,但无论我如何尝试,都无法使它们正常工作。 下面是我到目前为止的代码。希望有人能帮我理

我是拉威尔的新手,我对这一点肯定是哑口无言的,因为我已经阅读了文档,我在谷歌上搜索了很多次,但我不知道该怎么做。我在画廊和艺术家之间有一种M:M的关系。在每个图库编辑页面中,我都有一个表单,用于更新图库的名称和url。在同一页面中,我有两个其他选择表单,一个用于向库中添加艺术家,另一个用于删除艺术家,需要更新名为库中艺术家的透视表。我为这两个表单创建了两个自定义方法,分别称为postAdd和postRemove,但无论我如何尝试,都无法使它们正常工作。 下面是我到目前为止的代码。希望有人能帮我理解我犯的愚蠢的错误

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

}
控制器-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 添加表单


我已经对代码做了很多修改,很多事情可能会混淆。如果是这样的话,很抱歉。

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

将复选框替换为select应该不会有太多额外的工作,但我建议在这种情况下使用multi-select,因为从用户的角度来看,它会更简单,也更易于使用。如果必须修改答案,请告诉我是否应该修改答案

控制器 看法 编辑 只是让你的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,那么这应该是您所需要的全部,并且不需要输入类

但通常情况下,您只需传入画廊id,您将为其生成链接,它将位于URI中,艺术家将通过表单传入,在这种情况下,您需要使用Input::get'add_Artister',这将使您的URI更干净


postRemove函数将完全相同,只是您希望改用detach。当然,这都是假设负责传递画廊id和艺术家id的所有其他功能以及您已经在模型中设置的关系都正常工作。

谢谢,我非常感谢您的回答。我还没有用复选框尝试过你的建议。很抱歉,我今天花了几个小时试图理解你的建议逻辑,并进行了更多的研究,以便我可以通过选择输入来解决这个问题。仍然没有成功。这可能是一个顽固的用户界面选择,但我宁愿通过选择来实现这一点。如果我能理解如何解决postAdd方法。。。我就是不明白如何将输入id附加到数据透视表。。。我对此非常着迷=/我在我的答案中添加了一个更新的postAdd函数,希望它能为您解决问题..我刚刚开发了整个过程,因为您正在做的一些事情对URI没有多大意义,等等。。。希望这将有助于解决您可能遇到的任何问题。你可以在这里查看。。。非常感谢你!这确实帮了大忙!!
{{ 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() }}
Route::post('admin/galleries/{galleries}/add/{aid}', 'GalleriesController@postAdd');
Route::post('admin/galleries/{galleries}/remove/{aid}', 'GalleriesController@postRemove');
Route::resource('admin/galleries', 'GalleriesController');
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'));
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();
}