CRUD: How to avoid building whole Form for Delete button

There is one annoying thing in Laravel RESTful approach – if you want to have Edit/Delete links in your tables, Edit is done easy with a link to URL, but for Delete you have to build the whole form. Is there a way to avoid it?

Let’s start with WHY

First – what I’m talking about: you have probably seen/used something like that in your Views:

<a href="{{ url('items/'.$row->id.'/edit') }}">Edit</a> | 
{{ Form::open(['route' => ['item.delete', $row->id], 'method' => 'delete']) }}
<button type="submit">Delete</button>
{{ Form::close() }}

Probably some of you wonder why it’s different for Edit and Delete? Why the hell this form is even needed – couldn’t Taylor just built-in a simple another link and delete() function with GET method?

why-meme

The answer lies in security – all Forms in Laravel by default are protected with CSRF token, and you can add more on top of that with Middleware. And since Delete is a really sensitive method (you don’t want to lose your data by mistake, do you?), we better secure it properly.

Therefore if you think about cutting the corners and do something like building your own getDelete() function and make a link to GET method it from the View – that’s fine, but the risk is on you.

But it’s… not convenient

Well yeah, kind of. If you really want to save several lines of code and are too lazy to style your form buttons to look pretty, there is a way. To “fake” form submission with JavaScript. So “Delete” button would actually be a link, and then you catch its click by its class or some data-xxx property. Then you read the URL of the link, form the JS parameters and send the request to real Delete URL (by the way, did you know that there’s actually no DELETE method, it’s a POST).

That’s a theory, and I’m sure you could find different implementations of this JavaScript code. One of them I’ve found on GitHub – a piece of JavaScript code by soufiane EL HAMCHI. Here’s Laravel.js, which is actually a fork of Jeffrey Way’s Laravel.js – just for making it work with Laravel 5 version.

Usage is explained there – you just put Delete button as a link, like this:

<a href="posts/2" data-method="delete" data-token="{{csrf_token()}}" data-confirm="Are you sure?"></a>

And then JavaScript code catches “data-method” and does the magic. And don’t forget csrf_token().

Use with caution

Personally, I’m not a fan of this approach, cause not only it feels “hacky”, but it also makes your code less readable. Imagine a new developer joining your project or maintaining it after you – it would take additional time for him to understand how that Delete is processed, then to find where exactly is that JavaScript code etc. It’s not that hard to build a form with several line and style it with CSS, right?

Like our articles?
Check out our Laravel online courses!

8 COMMENTS

  1. Using a GET request to delete an entity is a BAD IDEA ™.

    HTTP methods carry semantic meaning. Using a GET request to perform an action breaks the web.

    To use just one example: if for whatever reason your browser decides to “prefetch” the data behind that link, you’ll have inadvertently deleted your entity.

    (I know on this case it won’t work, because it won’t have the token and method, but the point still stand).

  2. Most importantly, by making a Get request that performs any action other than reading data, you are giving a chance for web crawlers to cause a disaster on your site by mistake.

  3. Are you seriously scratching your head as to why a web page would submit requests with forms as opposed to pure JavaScript? Does it really need to be explained to you why you should design your pages in a way that can still send requests without JavaScript?

LEAVE A REPLY

Please enter your comment!
Please enter your name here