26

我将使用 HTML 链接销毁我的用户,但它似乎没有生成正确的链接,我做错了什么?

public function destroy($id)
{
    //Slet brugeren
    $e = new User($id);
    $e->destroy();

    //Log også brugeren ud
    Auth::logout();

    //redrect til forsiden
    Redirect::to("users/create");
}

在我看来,我称之为 {{URL::action('UserController@destroy', array($user->id))}}

4

9 回答 9

33

Laravel 5.x 更新 08/21/2017

该问题询问有关 Laravel 4 的问题,但我将其包括在内,以防寻找 Laravel 5.x 答案的人在这里结束。从 5.x 开始,表单助手(和其他一些)不可用。如果您正在执行 GET 或 POST 之外的操作,您仍然需要在表单上指定一个方法。这是实现这一目标的当前方法:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    <!-- other inputs... -->
</form>

您也可以使用{{ method_field('PUT') }}而不是写出隐藏的_method输入。

请参阅https://laravel.com/docs/5.4/routing#form-method-spoofing

Laravel 4的原始答案

我认为当您单击链接时,它可能正在向该端点发送 GET 请求。Laravel 中的 CRUD 根据 REST 工作。这意味着它期待一个 DELETE 请求而不是 GET。

这是Boris Strahija的教程中的一种可能性。

    {{ Form::open(array('route' => array('admin.pages.destroy', $page->id), 'method' => 'delete')) }}
        <button type="submit" class="btn btn-danger btn-mini">Delete</button>
    {{ Form::close() }}

这样,您可以使用 DELETE 方法以表单形式发送请求。文章解释了为什么传统链接不起作用:

您可能会注意到删除按钮位于表单内。原因是我们控制器的destroy()方法需要一个DELETE请求,这可以通过这种方式完成。如果按钮是一个简单的链接,请求将通过 GET 方法发送,我们不会调用 destroy() 方法。

于 2013-10-28T21:11:00.790 回答
18

一个很酷的 ajax 解决方案是这样的:

function deleteUser(id) {
    if (confirm('Delete this user?')) {
        $.ajax({
            type: "DELETE",
            url: 'users/' + id, //resource
            success: function(affectedRows) {
                //if something was deleted, we redirect the user to the users page, and automatically the user that he deleted will disappear
                if (affectedRows > 0) window.location = 'users';
            }
        });
    }
}

<a href="javascript:deleteUser('{{ $user->id }}');">Delete</a>

在 UserController.php 我们有这个方法:

public function destroy($id)
{
    $affectedRows  = User::where('id', '=', $id)->delete();

    return $affectedRows;
}

 

于 2014-10-20T18:35:35.690 回答
15

另一个“干净”的解决方案是使其成为 Rails 方式,如此处所述

  1. 公开创建一个新的 .js 文件并编写此函数:

    $(function(){
       $('[data-method]').append(function(){
            return "\n"+
            "<form action='"+$(this).attr('href')+"' method='POST' style='display:none'>\n"+
            "   <input type='hidden' name='_method' value='"+$(this).attr('data-method')+"'>\n"+
            "</form>\n"
       })
       .removeAttr('href')
       .attr('style','cursor:pointer;')
       .attr('onclick','$(this).find("form").submit();');
    });
    
  2. 在包含 jQuery 之后,不要忘记在模板中包含 .js 文件。

  3. 使用经典link_to()link_to_method()函数创建链接以删除记录。只要记住包含"data-method"="DELETE"参数:

    {{ link_to_route('tasks.destroy', 'D', $task->id, ['data-method'=>'delete']) }}
    

我喜欢这个,它看起来比Form::open();在刀片模板中膨胀你的代码要干净得多。

于 2014-04-15T11:25:46.117 回答
8

这是一个古老的问题,但我只是在寻找一个快速的答案,对这些都不满意。我会建议任何有同样问题的人创建一条新路线。过分担心 crud 合规性是愚蠢的,因为 HTML 没有这样的事情。无论是隐藏的表单字段还是获取路径,任何解决方案都只能勉强适应。

所以,在你的路线中,你可能有这样的事情:

Route::resource('users', 'UsersController'); 这样做的问题是,到达“destroy”方法的唯一方法是发送一个 post 请求,该请求具有一个名为“_method”的隐藏输入和一个值为“DELETE”的值。

只需在该行下添加: Route::get('users/{id}/destroy',['as'=>'users.delete','uses'=>'UsersController@destroy']);

现在您有了可以从 、 或任何您喜欢的方法访问的HTML::linkRoute路线Route::url

例如: {{ HTML::linkRoute( 'users.delete', 'Delete' , [ 'id' => $user->id ]) }}

编辑

我想澄清一下,尽管我已经解释了为什么向后弯腰以适应 crud 合规性有点愚蠢,但如果仅通过 POST 请求进行更改,您的应用程序仍然会更安全。

于 2014-12-19T20:18:20.363 回答
8

对于那些希望在 Laravel 5 中创建删除按钮的人:

{!! Form::open(['action' => ['UserController@destroy', $user->id], 'method' => 'delete']) !!}
  {!! Form::submit('Delete', ['class'=>'btn btn-danger btn-mini']) !!}
{!! Form::close() !!}

这与 Tayler 的回答类似,但我们使用新的刀片转义标签({!!!!}),我们使用Form外观生成按钮,并使用更优雅的方法链接到控制器。

在 Laravel < 5 中,Forms & HTML 包被自动引入。在 Laravel 5 中,我们必须将此包添加到composer.json

...
"required": {
  ...
  "laravelcollective/html": "^5.1"
}
...

现在添加服务提供者和别名config/app.php

...
'providers' => [
  ...
  Collective\Html\HtmlServiceProvider::class,
],

'aliases' => [
  ...
  'Form' => Collective\Html\FormFacade::class,
  'Html' => Collective\Html\HtmlFacade::class,
],

以上将输出

<form method="POST" action="https://yourdomain.tld/users/1" accept-charset="UTF-8">
  <input name="_method" type="hidden" value="DELETE">
  <input name="_token" type="hidden" value="xxxCrAZyT0K3nsTr!NGxxx">
  <input class="btn btn-danger btn-mini" type="submit" value="Delete">
</form>

如果您使用的是不同的表单生成器,只需确保它生成与上述类似的内容。

于 2015-03-01T19:09:14.663 回答
4

想要在表单外发送 DELETE 请求?

好吧,Jeffrey Way创建了一个不错的 javascript,它为您创建了一个表单并使用它,您只需要添加data-method="delete"到您的删除链接。

要使用,请导入脚本data-method="DELETE",并使用该属性创建链接。

脚本 :

(function() {

  var laravel = {
    initialize: function() {
      this.methodLinks = $('a[data-method]');

      this.registerEvents();
    },

    registerEvents: function() {
      this.methodLinks.on('click', this.handleMethod);
    },

    handleMethod: function(e) {
      var link = $(this);
      var httpMethod = link.data('method').toUpperCase();
      var form;

      // If the data-method attribute is not PUT or DELETE,
      // then we don't know what to do. Just ignore.
      if ( $.inArray(httpMethod, ['PUT', 'DELETE']) === - 1 ) {
        return;
      }

      // Allow user to optionally provide data-confirm="Are you sure?"
      if ( link.data('confirm') ) {
        if ( ! laravel.verifyConfirm(link) ) {
          return false;
        }
      }

      form = laravel.createForm(link);
      form.submit();

      e.preventDefault();
    },

    verifyConfirm: function(link) {
      return confirm(link.data('confirm'));
    },

    createForm: function(link) {
      var form = 
      $('<form>', {
        'method': 'POST',
        'action': link.attr('href')
      });

      var token = 
      $('<input>', {
        'type': 'hidden',
        'name': 'csrf_token',
          'value': '<?php echo csrf_token(); ?>' // hmmmm...
        });

      var hiddenInput =
      $('<input>', {
        'name': '_method',
        'type': 'hidden',
        'value': link.data('method')
      });

      return form.append(token, hiddenInput)
                 .appendTo('body');
    }
  };

  laravel.initialize();

})();
于 2015-02-09T22:35:04.470 回答
2

对于那些希望在 laravel 5 中使用锚标签创建删除按钮的人。

{!! Form::open(['action' => ['UserController@destroy', $user->id], 'method' => 'DELETE', 'name' => 'post_' . md5($user->id . $user->created_at)]) !!}
    <a href="javascript:void(0)" title="delete" onclick="if (confirm('Are you sure?')) { document.post_<?= md5($user->id . $user->created_at) ?>.submit(); } event.returnValue = false; return false;">
        <span class="icon-remove"></span>
    </a>
{!! Form::close() !!}
于 2015-09-13T11:05:30.640 回答
1

我试过你的代码,像这样使用它并且工作:

    <a href="{{URL::action('UserController@destroy',['id'=>$user->id]) }}" 
onclick=" return confirm('Are you sure you want to delete this?')" 
class="btn btn-default">
   DELETE     </a>

我认为唯一的问题在于您的数组:

['id'=>$user->id]
于 2015-09-07T12:34:33.823 回答
0
{{Form::open(['method'=>'delete','action'=>['ResourceController@destroy',$resource->id]])}}
 <button type="submit">Delete</button>                      
{{Form::close()}}   
于 2014-12-17T09:06:38.173 回答