Esta es la última entrega sobre la serie cómo crear un módulo CRUD de usuarios, y en este último capítulo veremos cómo borrar un registro con Laravel, además usaremos jQuery y AJAX.
En los capítulos previos vimos:
- Cómo crear las rutas y el controlador
- Cómo integrar un layout de Twitter Bootstrap
- Crear un formulario
- Validar y guardar un formulario
- Listar y paginar registros
- Editar registros
Para hacer más sencillo este tutorial y en general casi cualquier problema, vamos a separar el proceso por partes. Primero vamos a aprender cómo borrar un registro sin AJAX.
En nuestro formulario de usuarios vamos a colocar lo siguiente:
app/view/admin/users/form.blade.php
Código :
@if ($action == 'Editar') {{ Form::model($user, array('route' => array('admin.users.destroy', $user->id), 'method' => 'DELETE', 'role' => 'form')) }} <div class="row"> <div class="form-group col-md-4"> {{ Form::submit('Eliminar usuario', array('class' => 'btn btn-danger')) }} </div> </div> {{ Form::close() }} @endif

Fíjense que como yo uso la misma plantilla para crear y para editar debo agregar el @if para que la opción de eliminar se muestre sólo si el usuario está trabajando sobre un registro existente.
El resto es similar a lo que ya hemos visto. Sólo que para construir la ruta se usa admin.users.destroy (destroy no delete) y el método es DELETE en vez de POST o PATCH.
Al hacer click sobre este botón no verán nada. Pero si vamos al controlador app/controllers/admin/UsersController.php y agregamos lo siguiente al método destroy:
Código :
public function destroy($id) { return "Eliminando el registro $id"; }
Entonces al cliquear eliminar verán un mensaje. Eso quiere decir que ya nuestra vista funciona. Ahora veamos cómo hacer para que el registro se borre realmente.
Hay 2 formas:
Código :
public function destroy($id) { $user = User::find($id); if (is_null ($user)) { App::abort(404); } $user->delete(); return Redirect::route('admin.users.index'); }
Nos traemos el registro, verificamos que exista y por último llamamos al método delete.
La segunda es más sencilla:
Código :
public function destroy($id) { User::destroy($id); return Redirect::route('admin.users.index'); }
Este método más simple sólo acepta como parámetro la ID de un registro, en este caso un usuario y borra el mismo.
A mí me gusta más el primer método porque es más orientado a objetos. Quizás además de borrar al usuario necesitemos borrar algunas imágenes asociadas a éste o hacer otra operación, en ese caso es más conveniente el primer método.
Si hacemos click en el botón eliminar seremos redireccionados a la lista pero veremos cómo el registro seleccionado antes fue eliminado.
Agregar la opción de eliminar a la lista
En views/admin/users/list.blade.php vamos a agregar un link que nos servirá para llamar el javascript para eliminar un registro:
Código :
<a href="#" data-id="{{ $user->id }}" class="btn btn-danger btn-delete"> Eliminar </a>
Este link lo van a agregar al lado del botón editar, de forma que quede así:

Ahora vamos a agregar al final de la misma plantilla, justo antes del @stop lo siguiente:
Código :
{{ Form::open(array('route' => array('admin.users.destroy', 'USER_ID'), 'method' => 'DELETE', 'role' => 'form', 'id' => 'form-delete')) }} {{ Form::close() }}
Esto nos va a dar un form oculto que servirá para llamar a la acción de delete como en el ejemplo anterior, pero esta vez con javascript.
Noten que acá el ID lo dejé como un texto USER_ID, luego lo reemplazaré por el ID correcto, también con Javascript.
Ahora vamos a crear un nuevo archivo en public/assets/js/admin.js con lo siguiente:
Código :
$(window).ready(function () { if ( $ ('.btn-delete').length) { $('.btn-delete').click(function () { var id = $(this).data('id'); $(this).parents('tr').fadeOut(1000); }); } });
Y por supuesto tenemos que llamar al script, para ellos agreguemos:
Código :
{{ HTML::script('assets/js/admin.js') }}
En app/views/admin/layout.blade.php justo antes del </body>.
Si recargamos la lista y hacemos clic en el botón “eliminar” de cualquier usuario de la lista veremos cómo dicha fila se desvanece, esto gracias al jQuery, pero si presionamos F5 veremos que el usuario aún no ha sido eliminado, esto es porque aún falta:
Hacer la petición AJAX para eliminar el usuario
Primero vamos a adaptar nuestra acción de eliminar en app/controllers/admin/UsersController.php para que esté preparada para el AJAX:
Código :
public function destroy($id) { $user = User::find($id); if (is_null ($user)) { App::abort(404); } $user->delete(); if (Request::ajax()) { return Response::json(array ( 'success' => true, 'msg' => 'Usuario ' . $user->full_name . ' eliminado', 'id' => $user->id )); } else { return Redirect::route('admin.users.index'); } }
Las primeras líneas quedan igual, pero al final vamos a decidir que si la petición es AJAX if (Request::ajax()) vamos a devolver un JSON usando el método Response::json de Laravel, como parámetro vemos un array asociativo de PHP con alguna información que podría resultar útil para el frontend.
Luego vamos a cambiar nuestro script de admin.js por lo siguiente:
Código :
$(window).ready(function() { if ($('.btn-delete').length) { $('.btn-delete').click(function() { var id = $(this).data('id'); var form = $('#form-delete'); var action = form.attr('action').replace('USER_ID', id); var row = $(this).parents('tr'); row.fadeOut(1000); $.post(action, form.serialize(), function(result) { if (result.success) { setTimeout (function () { row.delay(1000).remove(); alert(result.msg); }, 1000); } else { row.show(); } }, 'json'); }); } });
Éste no es un tutorial de Javascript sin embargo les voy a explicar un poco qué hace el nuevo código de admin.js
Primero obtenemos el ID del registro que es muy importante, éste estaba en un atributo data del link para eliminar colocado en la lista anteriormente:
Código :
<a ... data-id="{{ $user->id }}" … >
Segundo obtenemos el objeto form con Jquery, al que se le asignó un ID de HTML “form-delete” anteriormente.
Código :
{{ Form::open(array(..., 'id' => 'form-delete')) }}
Luego usando este objeto form para obtener el valor del atributo “action” que nos dará la URL que tenemos que invocar para eliminar el registro, PERO recuerden que estábamos usando un “placeholder” USER_ID por eso lo reemplazamos por el ID real que queremos eliminar, obtenido previamente:
Código :
var action = form.attr('action').replace('USER_ID', id);
A continuación se obtiene la fila del registro en cuestión:
Código :
var row = $(this).parents('tr')
$(this), en este caso corresponde al botón eliminar y el método “parents” de Jquery nos trae finalmente la fila donde se encuentra dicho botón, que es la fila (<tr>) del mismo usuario.
Luego desaparecemos la fila usando un efecto atractivo de jQuery:
Código :
row.fadeOut(1000);
Y abajo, el tan esperado método para eliminar la fila con AJAX:
Código :
$.post(action, form.serialize(), function (result) { //… }, 'json');
Vean que:
- Como primer parámetro usamos la variable action que ya tendrá la URL correcta para eliminar el registro.
- Como segundo parámetro serializamos los valores del form-delete (eso nos permite enviar los campos ocultos _method y el _csrf_token, necesarios para que la petición a Laravel sea válida).
- El tercer parámetro es un callback que se ejecutará una vez que la llamada al servidor haya finalizado con éxito.
- El cuarto parámetro le dice a Jquery que esperamos que la data obtenida de regreso esté en formato JSON.
Este callback tiene algo de código interesante que realmente no hace mucha falta, pero quiero que vean qué se puede hacer con la información retornada:
Código :
function(result) { if (result.success) { setTimeout(function() { alert(result.msg); row.delay(1000).remove(); }, 1000); } else { alert (‘El registro ‘ + result.id + ‘ no pudo ser eliminado’); row.show(); } });
Podríamos por ejemplo tener un escenario donde el registro no sea eliminado (por falta de permisos o algo así), en ese caso podemos hacer que si “result.success” es falso, la fila vuelva a aparecer en la lista y se muestre un mensaje de error.
Si result.success es verdadero entonces también podemos mostrar un mensaje de éxito y eliminamos el HTML de la fila del código.
Lo importante es notar que podemos usar los datos de JSON que devolvimos desde nuestro controlador para alterar la vista, mostrar un mensaje etc.
En los próximos días publicaré un último tutorial con el indice de esta serie de tutoriales y además el código final completo.
Bonus track: la acción “show” para mostrar el usuario

Para quienes hicieron el ejercicio anterior, aquí tienen un ejemplo de cómo podría quedar la acción show:
Código :
/** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { $user = User::find($id); if (is_null($user)) App::abort(404); return View::make('admin/users/show', array('user' => $user)); }
Y la vista app/views/admin/users/show.blade.php:
Código :
@extends ('admin/layout') @section ('title') User {{ $user->full_name }} @stop @section ('content') <h2>User #{{ $user->id }}</h2> <p>Full name: {{ $user->full_name }}</p> <p>Email: {{ $user->email }}</p> <p> <a href="{{ route('admin.users.edit', $user->id) }}" class="btn btn-primary"> Editar </a> </p> {{ Form::model($user, array('route' => array('admin.users.destroy', $user->id), 'method' => 'DELETE'), array('role' => 'form')) }} {{ Form::submit('Eliminar usuario', array('class' => 'btn btn-danger')) }} {{ Form::close() }} @stop
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por gilberto el 24 de Noviembre de 2013
pero en este ultimo de eliminar eh seguido todos los pasos para eliminar con ajax y no me ah dado resultado... = (
gilberto-blog :
pero en este ultimo de eliminar eh seguido todos los pasos para eliminar con ajax y no me ah dado resultado... = (
Usa http://paste.laravel.com para ver tu código y tratar de ayudarte en qué pudo haber salido mal.
Saludos.
Por Gilberto el 26 de Noviembre de 2013
mi archivo admin.js -> http://paste.laravel.com/1and
mi controlador -> http://paste.laravel.com/1ane
mi list.blade.php -> http://paste.laravel.com/1anf
de antemano gracias por tu ayuda
Para depurar en JS puedes usar la funcion alert, algo como alert ( form.attr('id') ) por ej. ver hasta qué punto funciona ese código JS, si se está cargando, etc.
También puedes usar firebug, chrome developer tools para ir depurando y conseguir el error.
Estás cargando el JS cierto?
Por Gilberto el 27 de Noviembre de 2013
y uso firefox como navegador, al cual le tengo firebug y este me arroja lo siguiente
SyntaxError: illegal character
}else { row.show(); } }, ‘json’);
no se si ese sera el error por el cual no me permite eliminar
ahhh y por cierto sin ajax si me elimina
Por Gilberto el 27 de Noviembre de 2013
http://foros.cristalab.com/como-aplico-esta-sentencia-sql-en-laravel-4-t111963/
te lo agradezco de corazón se que debes ser una persona ocupada pero estoy un poco estancado hay....
Te puse como una pequeña introducción de todas formas debes ver la documentación oficial y otras páginas externas, yo siempre lo hago, a mí me gusta el material en inglés, siempre es completo pero en español también hay buen material.
Gracias por registrarte en Cristalab e intentar hacer otros módulos a partir de mi ejemplo, me contenta ver que sí era un material genérico como intenté explicar y no algo específico!
Saludos!
Por gilberto286 el 28 de Noviembre de 2013
Por mundoff el 30 de Noviembre de 2013
Por [email protected] el 05 de Diciembre de 2013
Por jsalvag el 11 de Diciembre de 2013
jsalvag :
Si me pasas el codigo yo puedo intentar buscar el problema
Por irraco el 15 de Diciembre de 2013
irraco-blog :
Aún no! Si quieres puedes usar gist o paste.laravel.com para compartir tu código con todos
Por irraco el 16 de Diciembre de 2013
Por jramirezgranada el 17 de Diciembre de 2013
Por irraco el 17 de Diciembre de 2013
Por sergiowebdev el 31 de Diciembre de 2013
Y muchas gracias a Duilio por el tutorial. Es una pasada.
Saludos.
Por cavein el 21 de Enero de 2014
Saludos.
Por Pool el 29 de Enero de 2014
Por wualdo el 31 de Enero de 2014
Por tuxpato el 02 de Febrero de 2014
Por darwin_mn el 20 de Marzo de 2014
Por dimitriacosta el 21 de Mayo de 2014
Por luismalamoc el 23 de Mayo de 2014
En todo caso el único detalle que encontré fue que no funciona bien el Ajax con el botón eliminar desde la vista del Show que diste como bonus.
Por lo demás, está perfecto. Gracias!
Saludos.
Por iscnorena el 03 de Junio de 2014
Por cornelioroyer el 03 de Junio de 2014
<a href="#" data-id="{{ $user->id }}" class="btn btn-danger btn-delete">
Eliminar
</a>
Por Eduardo el 04 de Junio de 2014
dimitriacosta, una opción fácil es poner un 'confirm' después del evento clic del botón
cornelioroyer, revisa de nuevo a mi me funciono sin problema
Saludos
Por AlfonsoMonroyIV el 10 de Julio de 2014
<a href="{{ route('admin.marcas.destroy', $marca->id) }}" class="btn btn-primary">
Eliminar
</a>
Cuando lo intento hacer, me redirecciona a la pantalla de admin.marcas.edit...
revise el HTML resultante y me manda solo a marcas/
Bueno pues gracias de antemano.
Saludos!
Por el 10 de Julio de 2014
como lo tengo funciona bien, pero no alinea el boton eliminar con los otros dos...
Es mucha bronca hacer tanto js, bueno, siento que hay otra manera mas facil.
gracias.
Por Diego el 04 de Agosto de 2014
Por Francisco Castillo el 21 de Agosto de 2014
alguien tiene el código entero de la aplicación para poder comprobarlo y ver donde están los errores.
Quisiera felicitar a Duilio por este tutorial
Por edsonmgoz el 07 de Noviembre de 2014
Por jdalvarez18 el 17 de Noviembre de 2014
jdalvarez18 :
De nada
Y en mi sitio como tal podrás encontrar nuevos tutoriales y videotutoriales de Laravel: http://duilio.me/proyectos
Saludos!
Por Faustino Vasquez Lim el 26 de Diciembre de 2014
Por mike el 17 de Febrero de 2015
Por AlfonsoMonroyIV el 06 de Marzo de 2015
Por lobofox el 08 de Mayo de 2015