为什么我被重定向到显示而不是销毁路线

Why do I get redirected to show instead of destroy route

当我尝试注销时,我从 show 路径进入函数,而不是 destroy 路径。

这是视图中的注销按钮:

@if (Auth::check())
  <li>
    {{ HTML::linkRoute('account.destroy', 'Logout', Auth::user()->id) }}
  </li>
@endif

routes.php:

Route::get('/', [
    'as'   => 'home',
    'uses' => 'HomeController@index'
]);

Route::post('account/login', [
    'as'   => 'login',
    'uses' => 'AccountController@postLogin'
]);

Route::get('account/myprofile', [
    'as'   => 'account.myprofile',
    'uses' => 'AccountController@getPersonalProfile'
]);

Route::get('/account/activate/{code}', [
    'as'   => 'account.activate',
    'uses' => 'AccountController@getActivate'

]);

Route::resource('account', 'AccountController',
    ['except' => ['index']]);

以及 showdestroy 函数:

public function show($id)
{
    $user = User::find($id)->first();

    return View::make('account.visit_profile')->with('user', $user);
}

public function destroy($id)
{
    Auth::logout();
    Session::flush();

    return Redirect::route('home');
}

如果我将 show 放在 resource 路由的例外中,并为注销创建路由:

Route::get('/account/logout', [
    'as'   => 'account.destroy',
    'uses' => 'AccountController@destroy'

]);

然后我仍然被重定向到 show 函数。

我不明白为什么会这样。

对于足智多谋的控制器,为show路由和destroy路由生成的url是相同的,唯一的区别是用于访问它们的HTTP动词。 show方法使用GET请求访问,destroy方法使用DELETE请求访问。这两种方法相当于:

Route::get('account/{account}', ['as' => 'account.show', 'uses' => 'AccountController@show']);
Route::delete('account/{account}', ['as' => 'account.destroy', 'uses' => 'AccountController@destroy']);

HTML 锚标记只能执行 GET 请求,因此您无法通过 HTML 锚标记访问 destroy 操作。 link 将指向 'account/{account}' url,但它将使用 GET 请求,从而将您带到 show 方法。

基本的解决方案是,代替 HTML link,您需要一个提交 POST 请求的表单,该请求包含一个隐藏字段“_method”,其值为'DELETE'。这里有几个选项。

  1. 自己写表格。

    @if (Auth::check())
        <li>
            {{ Form::open(['route' => ['account.destroy', Auth::user()->id], 'method' => 'delete']) }}
                {{ Form::submit('Logout') }}
            {{ Form::close() }}
        </li>
    @endif
    

    如果需要,您可以使用 CSS 使 form/submit 按钮看起来像 link。

  2. 使用 javascript 库为您完成此操作。有几个版本的名为 'restfulizer.js' 的小库四处流传。另一种选择是 rails jquery-ujs 库(在 rails 之外工作)。这些库背后的主要思想是,您所做的就是向 HTML 锚标记添加一个新的数据属性,库将负责为您生成和提交表单。例如,如果您加载了这两个库中的任何一个,您的代码将如下所示:

    @if (Auth::check())
        <li>
            {{ HTML::linkRoute('account.destroy', 'Logout', Auth::user()->id, ['data-method' => 'DELETE']) }}
        </li>
    @endif
    

    这就是您所需要的。 javascript 会处理剩下的事情。