编辑时唯一的密钥冲突


Unique key violation upon edit

我正在尝试更新一篇博客文章,但我从数据库部分得到了唯一的密钥错误,然后我没有使用模型,也没有直接访问ORM,但再次没有成功。

这是我专门编辑的路线

Route::get('/getedit/{slug}', array('as' => 'getedit', 'uses' => 'AdminController@getEdit'))->before('auth');
Route::post('/postedit', array('as' => 'postedit', 'uses' => 'AdminController@postEdit'))->before('auth');

控制器

public function getEdit($slug)
{
    $article = Post::where('slug', '=' , $slug)
        ->firstOrFail();
return View::make('admin.edit', array(
    'title' => $article->title,
    'mainarticle' => $article->article,
    'slug' => $article->slug,
    'category' => $article->category
));
}
// Updates articles to database
public function postEdit()
{
    $rules = [
        'title' => 'required',
        'article' => 'required',
    'slug' => 'required|unique:posts,slug,9',
    'category' => 'required'
];
$input = Input::all();
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
    return Redirect::route('getedit')
        ->withErrors($validator);
        // withInput not defined
}
else
{
    $slug = $input['slug'];
    /*$affectedRows = Post::where('slug', '=', $slug)->update([
                'title' => $input['title'],
                'article' => $input['article'],
                'slug' => $input['slug'],
                'category' => $input['category']
            ]);*/
    /*$affectedRows = Post::where('slug', '=', $slug)->firstOrFail();
    $affectedRows->title = $input['title'];
    $affectedRows->article = $input['article'];
    $affectedRows->slug = $input['slug'];
    $affectedRows->category = $input['category'];
    $affectedRows->save();*/
    $post =  DB::table('posts')->where('slug', '=', $slug)->update([
            'title' => $input['title'],
            'article' => $input['article'],
            'slug' => $input['slug'],
            'category' => $input['category']
        ]);

    if ($post) {
        return Redirect::route('dashboard')
            ->with('flash_message','Article Successfully Inserted');    
    }
    else
    {
        return Redirect::route('dashboard')
            ->with('flash_message','Error updating data');      
    }
}
}

我的模型只是创建数据库的对象(我只是在尝试这个框架,无意中遵循了胖控制器和瘦模型的方法)。我尝试过使用Post::find(1)->update($data);方法,但这返回了唯一的冲突,而我当前的方法只是执行更新失败时触发的else语句。

注:我是拉拉威尔的新手,第一次尝试这个。

当你更新帖子时,你宁愿发送一个POST(或更好的PATCH/PUT-http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)对给定资源的请求。

也就是说,您将在url中包含编辑后的行密钥,并将您的方法更改为以下内容:

// route
Route::post('/postedit/{id}', array('as' => 'postedit', 'uses' => 'AdminController@postEdit'))
    ->before('auth');
// controller
public function postEdit($id)
{
    // if no posts with $id found, throws exception - catch it and eg. show 404
    $post = Post::findOrFail($id);
    $rules = [
        'title' => 'required',
        'article' => 'required',
        'slug' => 'required|unique:posts,slug,'.$id, // to ignore this row in unique check
        'category' => 'required'
    ];
    // validate
    $post->fill($input)->save(); // fill() in order to use mass-assignement check
    // alternatively you can just update:
    // $post->update($input);
    // but then make sure $input has only elements corresponding to the table columns

此外,请阅读有关路由分组的信息,这样您就不需要将before('auth')单独添加到这些路由中。

您应该检查数据库表索引。您应该确保只有slug具有唯一索引。

我看到你在检查鼻涕虫的唯一性,但你在规则中硬编码了9:

'slug' => 'required|unique:posts,slug,9',

应该是:

'slug' => 'required|unique:posts,slug,'.$id,

其中,您尝试编辑的帖子的$id id。

你应该在你的表单中包括这样的id作为隐藏元素,而不是用你拥有的slug搜索记录,因为你似乎可以编辑你的slug,你可能会编辑错误的记录或什么都不编辑。