为什么我被重定向到show而不是destroy route

时间:2015-03-07 23:46:21

标签: php laravel laravel-4 routing

当我尝试退出时,我从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函数。

我无法理解为什么会这样。

1 个答案:

答案 0 :(得分:1)

对于资源丰富的控制器,为show路由和destroy路由生成的URL是相同的,唯一的区别是用于访问它们的HTTP动词。使用GET请求访问show方法,并使用DELETE请求访问destroy方法。这两种方法相当于:

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

HTML锚标记只能执行GET请求,因此您无法通过HTML锚标记访问destroy操作。该链接将指向“account / {account}”网址,但会使用GET请求,从而转到show方法。

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

  1. 自己写表格。

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

    如果需要,您可以使用CSS使表单/提交按钮看起来像一个链接。

  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会处理其余的事情。