使用Laravel 5.4从数据库中删除数据

3
我对Laravel框架比较陌生,正在构建一个简单的博客。我已经能够创建博客、显示博客和展示所有博客的概述。现在我想删除一篇博客。因此,在我的视图中创建了一个带有路由链接的删除按钮,该链接还将传递文章的id。然后,在我的路由文件中,我指定了一个删除请求和一个控制器方法。 在该方法中,我查找id并尝试使用我在路由/视图中指定的id删除行。

这不起作用。它不会触发destroy/delete方法,而是显示文章,触发show方法而不是delete方法。 有人可以帮我解决问题吗?我做错了什么?

View.blade.php

<a href="{{route('nieuws.destroy', ['id' => $blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
  <i class="fa fa-trash"></i>
</a>

路由

Route::group(['middleware' => 'auth'], function () {

    Route::get('/aanvragen', 'aanvragenController@index')->name('aanvragen.index');

    Route::get('/logout' , 'Auth\LoginController@logout')->name('logout');

    Route::get('/nieuws/toevoegen', 'blogController@create')->name('blogs.add');

    Route::post('/nieuws/store', 'blogController@store')->name('nieuws.store');

    Route::delete('/nieuws/{id}', 'blogController@destroy')->name('nieuws.destroy');

});

Route::get('/nieuws', 'blogController@index')->name('blogs.index');

Route::get('/nieuws/{blog}', 'blogController@show')->name('blogs.show');

控制器方法

删除/销毁

public function destroy($id) {

    $blog = Blog::find($id);

    $blog->delete();

    return redirect('/nieuws');

}

展示
public function show(Blog $blog) {

    dd('show');


    return view('blogs.show', compact('blog'));

}

1
@Gijsberts,您可能需要重新检查Kunal的答案。允许GET请求以任何方式更改数据是不良惯例和安全风险。 - Robert
4个回答

3

delete()路由需要您将数据POST过来。

HTML表单只支持GET和POST两种方法,不支持DELETE、PUT等其他方法,这就是为什么Laravel使用_method来欺骗HTML表单的不足方法。

在这些情况下,您不要使用GET,因为某个人可以通过即时通讯或电子邮件向用户发送URL(http://yoursite.com/blog/delete/1),用户单击链接后博客将会被删除。

定义您的路由方式应与使用资源控制器时相同,如下:

Route::delete('/nieuws/{id}', 'blogController@destroy')->name('nieuws.destroy');

您可以使用带有删除方法的表单:

// apply some inline form styles
<form method="POST" action="{{ route('nieuws.destroy', [$blog->id]) }}">
    {{ csrf_field() }}
    {{ method_field('DELETE') }}
    <button type="submit">Delete</button>
</form>

或者像SR_在您的原始帖子中评论中提到的那样,进行一些JavaScript魔法。


另外,为您的destroy操作添加某种验证。目前当您提供不存在的id或其他内容时,会收到500错误,而不是您想要的404。

public function destroy($id)
{
    $blog = Blog::findOrFail($id);

    $blog->delete();

    return redirect('/nieuws');
}

1

我认为你需要更新你的destroy函数,类似于:

public function destroy($id) {

    $blog = DB::table('blog')->where('id',$id)->delete();

    return redirect('/nieuws');

}

并且更新你的视图代码如下:
<a href="{{route('nieuws.destroy', [$blog->id])}}" onclick="return confirm('Weet je dit zeker?')">
  <i class="fa fa-trash"></i>
</a>

希望这对你有用!

很遗憾,因为那不是问题所在。问题是我的控制器显示了@show方法而不是@destroy方法。 - Giesburts
@Gijsberts 在 show 方法中,blog 的结果是什么? - AddWeb Solution Pvt Ltd
仅提供博客详细信息和来自数据库的数据。为了测试目的,我现在使用数据转储功能来查看它是否激活了显示方法。 - Giesburts

0

我也是 Laravel 的新手,但我通过以下方式使其工作:

(我使用“Article”作为模型名称,并且路由中的resource“方法”代表一堆有用的路由,包括您编写的路由)

控制器:

public function destroy($id){
        Article::find($id)->delete();
        //$article = Article::find($id);
        return redirect()->back()->withErrors('Successfully deleted!');
    }

路由:

Route::resource('article','ArticleController');

然而,我认为问题在于您的模型默认定义的数据库名称。Laravel会假设您有一个名为“blogs”的数据库,因为您有一个名为“blog”的模型。您确定数据库名称正确吗?


是的,那不是问题,因为我也可以添加博客并显示它们。问题在于销毁路由与显示路由冲突。它激活了显示方法而不是销毁方法。 - Giesburts
将视图更改为以下内容如何: <form action="{{ url('admin/blog/'.$blog->id) }}" method="POST" style="display: inline;"> {{ method_field('DELETE') }} {{ csrf_field() }} <button type="submit" class="btn btn-danger">删除</button> </form> - Tan Yuanhong

0

要使用 DELETE HTTP 动词,您的表单应该包含 POST 方法并设置 method_field('DELETE')

例如:

<form method="POST" action="{{ route('xxx.destroy', $xxx->id) }}">
    {{ csrf_field }}
    {{ method_field('DELETE') }}
</form>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接