【问题标题】:Laravel conflicting routesLaravel冲突路线
【发布时间】:2015-01-29 20:49:20
【问题描述】:

我的routes.php摘录:

Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function() {

    Route::resource('posts', 'PostsController', [
        'except' => ['show']
    ]);

    Route::delete('posts/trash', [
        'as' => 'posts.trash.empty',
        'uses' => 'PostsController@emptyTrash'
    ]);

});

我的PostsController.php摘录:

/**
 * DELETE /admin/posts/{id}
 */
public function destroy($id)
{
    // code
}

/**
 * DELETE /admin/posts/trash
 */
public function emptyTrash()
{
    // code
}

问题在于 Laravel 将 DELETE /admin/posts/trash 请求中的“垃圾”字符串混淆为 {id} 参数。因此,将调用 destroy() 方法而不是 emptyTrash()。为什么以及我可以为此做些什么?

【问题讨论】:

  • 尝试更改路线的顺序。将Route::delete('posts/trash... 放在Route::resource... 之前
  • 是的,它有效。但我想知道为什么以及实际上比仅仅依靠订购更好的方法。也许一个模型绑定或一个 {id} 检查是一个 int?让它成为接受它的完整答案。

标签: php laravel routes laravel-5


【解决方案1】:

首先,顺序很重要。 Laravel 会按照你注册的顺序搜索匹配的路由。如您所见,Laravel 将 trash 作为 id,因此 URI 与资源路由匹配。由于该路由是在您的附加路由之前注册的,因此它将使用资源路由。

最简单的解决方法是更改​​该顺序:

Route::delete('posts/trash', [
    'as' => 'posts.trash.empty',
    'uses' => 'PostsController@emptyTrash'
]);

Route::resource('posts', 'PostsController', [
    'except' => ['show']
]);

如果您不喜欢这样,您可以尝试将资源路由的参数限制为仅数字。不幸的是,您不能像其他人一样将->where() 添加到资源路由中。

相反,您必须为路由参数定义global pattern。路由参数Route::resource选择的是资源名(snake_case)。

所以这应该适合你:

Route::pattern('posts', '[0-9]+');

【讨论】:

  • 太好了,Laravel 中的顺序很重要5.4
【解决方案2】:

在您看来,您应该有一个按钮或链接来实际删除帖子。视图应如下所示:

@section('content')
<div class="panel panel-default">
    <div class="panel-heading clearfix">
        <b>{{ $post->post_name . ' (id:' . $post->post_id . ')' }}</b><br />
        <b> {{ link_to_route('overview', 'Go Back To Post List') }}   </b>
        <div class="pull-right">
            // FORM FOR DELETING POST
            {{ Form::open(array('route' => array('delete_post', $post->post_id))) }}
                {{ link_to_route('edit_post', 'Edit Post', array('id' => $post->post_id), array('class' => 'post_img_button_edit')) }}
                {{ Form::hidden('_method', 'DELETE') }}
                {{ Form::submit('Delete Post', array('class' => 'post_img_button_delete')) }}
            {{ Form::close() }}
        </div>

      <div class="pull-right">
            // FORM FOR EMPTYING TRASH
            {{ Form::open(array('route' => 'empty_trash')) }}
                {{ Form::hidden('_method', 'DELETE') }}
                {{ Form::submit('Empty Trash', array('class' => 'post_img_button_delete')) }}
            {{ Form::close() }}
        </div>

    </div>

/* Additional HTML code within view */

你的控制器应该是这样的:

public function destroy($id)
{
    $this->post->delete($id);
    return \Redirect::route('overview'); 
}

public function emptyTrash()
{
  // code for collecting and emptying Trash
}

你的路线应该看起来像这样:

Route::delete('admin_posts/admin_posts/{id}/destroy', array('as'=>'delete_post', 'uses'=>'PostsController@destroy'));

Route::delete('posts/trash', array('as'=>'empty_trash', 'uses'=>'PostsController@emptyTrash'));

实际删除帖子的路径名称是'delete_post'

清空垃圾箱的路线名称将是empty_trash

基本上你明确定义了你的路线,这样你就可以避免歧义,Laravel 会知道要走哪条路线。希望这些信息对您有所帮助!

【讨论】:

  • 我已经尝试更改路由名称并将我的表单设置为:{!! Form::open(['method' =&gt; 'DELETE', 'route' =&gt; 'delete_post']) !!},但没有成功。
  • @AntonisGr 好的,给我几分钟。我将在上面编辑我的答案并提供更详细的解释。
  • 谢谢,但这不是问题。请看另一个答案。是路线顺序有问题!
  • @AntonisGr 没问题。正如 lukasgeiter 所说,您的路线顺序实际上很重要。我刚刚从使用 Laravel 中了解到,您必须明确定义路由的方式以及控制器实际调用它们的方式等。
猜你喜欢
  • 2017-04-15
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-27
  • 1970-01-01
  • 2018-11-30
  • 2018-10-01
  • 1970-01-01
相关资源
最近更新 更多