Restful Deleting In Laravel

A quick macro you can re-use in your Laravel apps to send DELETE requests with a CSRF token to a server

January 7, 2014

Reading time: 2min.

Restful deleting in Laravel can make newcomers to RESTful APIs scratch their head a bit. I know, cause I’m one of them. We’re used to just have a simple link pointing to a certain URI where the magic happens, but how do we set the HTTP verb if we’re not submitting any form?

Well, Jeffrey Way created a nice javascript that creates a form for you and to use it you only need to add data-method="delete" to your delete links. Smooth and clean, as always, but no CSRF handling unless you include the javascript directly in your views with a <script> tag. Zizaco, creator of Confide and Entrust also has a solution, but also - no CSRF handling. Here’s my quick’n’dirty fix, which is not nearly as elegant as theirs, but it does have the much needed CSRF handling.

Keeping it as simple as it can get, we’ll create a macro. If you don’t have one already, create the file /app/macros.php:

/*
|--------------------------------------------------------------------------
| Delete form macro
|--------------------------------------------------------------------------
|
| This macro creates a form with only a submit button. 
| We'll use it to generate forms that will post to a certain url with the DELETE method,
| following REST principles.
|
*/
Form::macro('delete',function($url, $button_label='Delete',$form_parameters = array(),$button_options=array()){

    if(empty($form_parameters)){
        $form_parameters = array(
            'method'=>'DELETE',
            'class' =>'delete-form',
            'url'   =>$url
            );
    }else{
        $form_parameters['url'] = $url;
        $form_parameters['method'] = 'DELETE';
    };

	return Form::open($form_parameters)
			. Form::submit($button_label, $button_options)
			. Form::close();
});

And than load it in /app/start/global.php like so:

require app_path().'/macros.php';

In your blade templates you generate the link like this:

{{Form::delete('resource/'. $resource->id, 'Delete')}}

Simple enough, right? You can comlicate it a bit adding more parameters for more control.

{{Form::delete('resource/'. $resource->id, 
    'Delete',
    array('id'=>'the_form_id','class' => 'the-delete-form'),
    array('class'=>'the-delete-link')
    )}}

Not that sleek, but functional.

And in the end let’s ask the user if they really really want to delete the resource:

$(document).on('submit', '.delete-form', function(){
	return confirm('Are you sure?');
});

That’s what I got. Here’s the gist, please feel free to fork it and let me know how we can make it better.

comments powered by Disqus