【问题标题】:CRUD Laravel 5 how to link to destroy of Resource Controller?CRUD Laravel 5如何链接到资源控制器的销毁?
【发布时间】:2015-07-29 17:18:58
【问题描述】:

我有链接

<a class="trashButton" href="{{ URL::route('user.destroy',$members['id'][$i]) }}" style="cursor: pointer;"><i class="fa fa-trash-o"></i></a> 

这个链接应该指向 Usercontroller 的 destroy 方法,这是我的路由Route::resource('/user', 'BackEnd\UsersController');

UserController 是一个资源控制器。但此时它正在引导我使用 show 方法而不是指向 destroy 方法

【问题讨论】:

    标签: php laravel laravel-5


    【解决方案1】:

    您需要发送DELETE 请求而不是GET 请求。您不能通过链接来做到这一点,因此您必须使用 AJAX 请求或表单。

    这里是通用的表单方法:

    <form action="{{ URL::route('user.destroy', $members['id'][$i]) }}" method="POST">
        <input type="hidden" name="_method" value="DELETE">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
        <button>Delete User</button>
    </form>
    

    如果您使用的是 Laravel 5.1 或更高版本,那么您可以使用 Laravel 的内置帮助程序来缩短您的代码:

    <form action="{{ route('user.destroy', $members['id'][$i]) }}" method="POST">
        {{ method_field('DELETE') }}
        {{ csrf_field() }}
        <button>Delete User</button>
    </form>
    

    如果您使用的是 Laravel 5.6 或更高版本,那么您可以使用新的 Blade 指令来进一步缩短您的代码:

    <form action="{{ route('user.destroy', $members['id'][$i]) }}" method="POST">
        @method('DELETE')
        @csrf
        <button>Delete User</button>
    </form>
    

    你可以阅读更多关于method spoofing in Laravel here.

    【讨论】:

    • 注意输入字段可以分别缩短为{{ method_field("DELETE") }}{{ csrf_field() }}
    • @AI0867 正确,如果您使用的是 5.1 或更高版本。
    • 请注意 Laravel 5.6 你有更短的代码:@csrf@method('DELETE')(我这边没有测试,抱歉)。
    • 我怎样才能用 ajax 做到这一点?
    • @LuísAlmeida 您可以将 AJAX 调用中的方法设置为DELETE,如@manix 接受的答案中所述,stackoverflow.com/a/30299435/4245525
    【解决方案2】:

    这是因为您通过 GET 方法而不是 DELETE 方法请求资源。看:

    DELETE  /photo/{photo}  destroy     photo.destroy
    GET     /photo/{photo}  show    photo.show
    

    两个路由具有相同的 URL,但标头动词标识要调用哪个。看起来RESTful table。例如,您可以通过 ajax 发送 DELETE 请求:

    $.ajax({
        url: '/user/4',
        type: 'DELETE',  // user.destroy
        success: function(result) {
            // Do something with the result
        }
    });
    

    【讨论】:

    • 有没有办法我可以通过 URL::route 发送该方法,以便 laravel 可以理解它的删除方法,而不是使用 ajax 或其他任何东西@manix
    • 通过网络浏览器,我不这么认为。您可以考虑制作控制器而不是资源。使用基本控制器,您可以声明一个可以删除用户的函数。
    • @manix 当我做同样的事情时,它会触发 TokenMismatchException 异常。即使我使用 ajax 请求发送 csrf 令牌。请指导
    【解决方案3】:

    我使用这个模板'resources/views/utils/delete.blade.php'

    <form action="{{ $url or Request::url() }}" method="POST">
        {{ method_field('DELETE') }}
        {{ csrf_field() }}
        <button type='submit' class="{{ $class or 'btn btn-danger' }}" value="{{ $value or 'delete' }}">{!! $text or 'delete' !!}</button>
    </form>
    

    这样称呼:

    @include('utils.delete',array( 'url' => URL::route('user.destroy',$id),'text' => '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> delete me'))
    

    【讨论】:

    • {{ csrf_field() }}{{ method_field('FOO') }} 在您拥有 Laravel 5.6 时已过时,请参阅上面的一些答案。
    【解决方案4】:

    如果您希望通过常规链接而不是通过 AJAX 或其他类型的表单请求来执行此操作,您可以设置一个特殊的路由来响应普通的GET 请求:

    在你的路线中,除了资源之外,还要定义它:

    Route::get('user/{site}/delete', ['as' => 'user.delete', 'uses' => 'UserController@destroy']);
    

    在你看来:

    <a href="{{ route('user.delete', $user->id) }}">Delete this user</a>
    

    在您的控制器中:

    public function destroy(User $user)
    {
      $user->delete();
      return redirect()->route('users.index');
    }
    

    【讨论】:

    • 虽然这有效,但它会为 GET 请求分配破坏性操作,并且容易受到 CSRF 的攻击。
    • 这是一种危险的行为。
    【解决方案5】:

    如果我们需要使用anchor来触发destroy路由,而我们又不想使用ajax,我们可以在我们的链接中放置一个表单,并使用onclick属性提交表单:

    <a href="javascript:void(0);" onclick="$(this).find('form').submit();" >
        <form action="{{ url('/resource/to/delete') }}" method="post">
            <input type="hidden" name="_method" value="DELETE">
        </form>
    </a>
    

    【讨论】:

      【解决方案6】:

      如果你真的想通过 HTML 访问删除路由的销毁操作,那么有一种使用 HTTP 方法欺骗的方法,这意味着你可以通过添加一个名为 _method 的隐藏输入来访问删除 HTTP 方法,其值为的“删除”。 “PUT”和“PATCH”HTTP 方法可以使用相同的方法。

      以下是 DELETE 方法的示例。

      <form action="/tasks/5" method="POST">
      <input type="hidden" name="_method" value="DELETE">
      </form>
      

      会得到路线

      DELETE  /tasks/{id}  destroy     tasks.destroy
      

      如果你使用 laravel 集体,你可以在你的视图中这样写。

      {!! Form::open(['url' => '/tasks/'.$cat->id, 'method' => 'delete']) !!}
      {!! Form::submit('Delete', ['class' => 'btn btn-primary']) !!}
      {!! Form::close() !!}
      

      【讨论】:

        【解决方案7】:

        如果有人来这里寻找如何替换标准 laravel 表单以进行删除,从其中的按钮到链接,您只需替换:

        {!! Form::open(['method' => 'DELETE', 'route' => ['tasks.destroy', $task->id],'onsubmit' => 'return confirm("Are you sure?")', 'id'=>'himan']) !!}
        
            {!! Form::submit('Delete') !!}
        
        {!! Form::close() !!}
        

        {!! Form::open(['method' => 'DELETE', 'route' => ['tasks.destroy', $task->id],'onsubmit' => 'return confirm("Are you sure?")', 'id'=>'himan']) !!}
        
            <a href="#" onclick="$(this).closest('form').submit();">Delete</a>
        
        {!! Form::close() !!}
        

        只需将按钮替换为简单的&lt;a href="#"... 但带有onclick 属性即可提交表单!

        【讨论】:

          【解决方案8】:

          如果你想使用链接,你可以使用我创建的库,它可以让人们创建行为类似于 POST、DELETE... 调用的链接。

          https://github.com/Patroklo/improved-links

          【讨论】:

            【解决方案9】:

            GETDELETE 两个路由具有相同的 URL,但标头动词标识要调用哪个。

            这是我用于编辑和删除的代码 sn-ps。我使用引导模式确认删除操作

            <div class="btn-group">
              <a href="{{ route('locations.edit', $location->id) }}"
               class="btn btn-default btn-sm">
                <i class="fa fa-pencil"></i>
              </a>
              <span class="btn btn-danger btn-sm formConfirm"
                  data-form="#frmDelete-{{$location->id}}"
                  data-title="Delete Location"
                  data-message="Are you sure you want to delete this Location ?">
                  <i class="fa fa-times"></i>
              </span>
            <form method="POST"
                  style="display: none"
                  id="frmDelete-{{$location->id}}"
                  action="{{ route('locations.destroy' , $location->id) }}">
                {!! csrf_field() !!}
                {{ method_field('DELETE') }}
                <input type="submit">
            </form>
            

            引导模式

            <div class="modal fade" id="formConfirm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
                                    class="sr-only">Close</span></button>
                        <h4 class="modal-title" id="frm_title">Delete</h4>
                    </div>
                    <div class="modal-body" id="frm_body"></div>
                    <div class="modal-footer">
                        <button style='margin-left:10px;' type="button" class="btn btn-primary col-sm-2 pull-right"
                                id="frm_submit">Yes
                        </button>
                        <button type="button" class="btn btn-danger col-sm-2 pull-right" data-dismiss="modal" id="frm_cancel">
                            No
                        </button>
                    </div>
                </div>
            </div>
            

            最后是 JS 代码

            $('.formConfirm').on('click', function (e) {
              e.preventDefault();
              var el = $(this);
              var title = el.attr('data-title');
              var msg = el.attr('data-message');
              var dataForm = el.attr('data-form');
            
              $('#formConfirm')
                .find('#frm_body').html(msg)
                .end().find('#frm_title').html(title)
                .end().modal('show');
            
              $('#formConfirm').find('#frm_submit').attr('data-form', dataForm);
            });
            
            $('#formConfirm').on('click', '#frm_submit', function (e) {
              var id = $(this).attr('data-form');
              $(id).submit();
            });
            

            【讨论】:

              【解决方案10】:

              我的非 ajax 版本。我在资源列表(数据表)的下拉列表(引导程序)中使用它。非常简短且通用。

              全局 jQuery 方法:

              $('.submit-previous-form').click(function (e) {
                  e.preventDefault();
                  $($(this)).prev('form').submit();
              });
              

              然后我们可以在任何地方使用这样的东西:

              {{ Form::open(['route' => ['user.destroy', $user], 'method' => 'delete']) }} {{ Form::close() }}
              <a href="#" class="dropdown-item submit-previous-form" title="Delete user"><i class="icon-trash"></i> Delete him</a>
              

              推荐:很容易与确认脚本集成,例如 swal。

              【讨论】:

                【解决方案11】:

                你可以试试这个:(你可以传递你的id)

                <form action="{{ route('tasks.destroy', $dummy->id) }}" method="post">
                            @csrf
                            @method('DELETE')
                 <a href="#" class="btn btn-danger" title="Delete" data-toggle="tooltip" onclick="this.closest('form').submit();return false;">
                              <i class="bi bi-trash-fill" style="color:white"></i>
                           </a>
                 </form>
                

                需要类似的路线:

                Route::get('/tasks/delete/{id}', 'TasksController@destroy')
                     ->name('tasks.destroy');
                

                你的控制器:

                public function destroy($id)
                {
                    $task = Task::find($id);
                    $task->delete();
                    return redirect('/home')->with('success','Task Deleted Successfully');
                }
                

                或者你可以试试这个

                 {!! Form::open(['method' => 'DELETE','route' => ['reports.destroy', $dummy->id],'class'=>'']) !!}
                      {{ Form::button('<i class="bi bi-trash-fill" style="color:white"></i>', ['type' => 'submit', 'class' => 'delete get-started-btn-two'] )  }}
                   {!! Form::close() !!}
                

                【讨论】:

                  猜你喜欢
                  • 2017-12-18
                  • 2013-11-07
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-09-05
                  • 1970-01-01
                  • 2021-06-01
                  • 2015-07-05
                  相关资源
                  最近更新 更多