Laravel 6

En este curso Primeros Pasos con Laravel 6 estamos creando un módulo CRUD de notas. CRUD proviene de las siglas de Create, Read, Update y Delete. Puesto que ya hemos completado las acciones para crear, mostrar y actualizar notas, nos falta la opción para eliminar, así que es en esto en lo que trabajaremos en esta lección.

Esta lección incluye un video premium

Regístrate para ver este video y cientos de lecciones exclusivas.

Mira el código en GitHub: actual, resultado, comparación.

Ruta para eliminar registros

Para procesar la eliminación de una nota, necesitaremos una nueva ruta, esta vez con el método DELETE:

<?php

// routes/web.php
Route::delete('notas/{id}', 'NoteController@destroy')
    ->name('notes.destroy');

Puedes notar que una vez más la URL notas/{id} ya fue usada en las rutas para mostrar y actualizar la nota. Pero debido a que esta nueva ruta usa el método DELETE es diferente.

Formulario para eliminar registros

Además -a menos que utilicemos JavaScript como veremos en la lección siguiente- vamos a necesitar un formulario para acceder a esta ruta.

Coloca lo siguiente al final del cuerpo de la nota en la plantilla notes.blade.php:

<!-- resources/views/note.blade.php -->
@forelse($notes as $note)
  <div class="card-body">
    <!-- El resto del codigo aqui -->

    <form method="POST" action="{{ url("notas/{$note->id}") }}">
      @csrf
      @method('DELETE')

      <button type="submit">Eliminar</button>
    </form>
  </div>
@empty
  <!-- ... -->
@endforelse

Si abres la aplicación en el navegador, deberías ver un pequeño botón que dice «Eliminar» debajo del contenido de la nota. Al hacer clic en este botón deberías ver el error:

Call to undefined method App\Http\Controllers\NoteController::destroy()

Si por el contrario ves el error The POST method is not supported for this route., asegúrate de agregar la directiva @method('DELETE') dentro del formulario.

Acción del controlador para eliminar registros

Ahora creemos la acción destroy del controlador con el código necesario para eliminar la nota y devolver al usuario a la página de inicio:

<?php

class NoteController
{
    public function destroy($id)
    {
        $note = Note::find($id);
        
        $note->delete();

        return redirect('/');
    }
}

Ahora si hacemos clic en eliminar podremos ver que la nota elegida ya no aparece en la lista.

Si buscamos en el administrador de base de datos podremos ver que efectivamente la nota ha sido eliminada.

Antes tenía la preocupación fútil de que era más óptimo enviar la petición para eliminar directamente sin cargar la nota antes:

<?php

class NoteController
{
    public function destroy($id)
    {
        DB::table('notes')->delete($id);
        
        return redirect('/');
    }
}

Si bien esto funciona, al obtener la nota antes podemos verificar que exista, como veremos en la lección sobre manejo de errores 404, además podemos obtener información del registro para, por ejemplo, mostrar un mensaje al usuario indicando que la nota con el título X o que el usuario con el nombre Y fue eliminado del sistema.

Además, si trabajamos con Eloquent tendremos algunos beneficios adicionales como, por ejemplo:

Eliminado lógico con Eloquent

Eloquent nos brinda la característica de Soft Delete o Eliminado Lógico para ayudarnos a prevenir la pérdida de datos, construir una papelera de reciclaje, etc.

Ya yo he hablado de esta característica con mucho detalle en lecciones como Crea una papelera en Laravel usando Soft Deletes de Eloquent ORM, pero permíteme mostrar un preview:

Vamos a agregar el trait SoftDeletes a nuestro modelo de esta forma:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Note extends Model
{
    use SoftDeletes;
    
    //...
}

Si ahora intentamos eliminar una nota usando Eloquent deberíamos ver el siguiente error:

Laravel - columna no encontrada

A pesar de que Ignition: la página de error de Laravel nos sugiere que ejecutemos las migraciones, hacer clic en el botón «Run migrations» no solucionará el problema.

Debemos agregar una columna a la tabla de notas, podemos hacerlo modificando la migración create_notes_table puesto que aún no hemos lanzado nuestra aplicación:

<?php

//...

class CreateNotesTable extends Migration
{
    public function up()
    {
        Schema::create('notes', function (Blueprint $table) {
            //...

            $table->softDeletes();
        });
    }

    //...
}

Luego re-ejecutemos php artisan migrate:fresh --seed en la consola.

También podríamos agregar una nueva migración, pero esto lo podemos ver luego.

Si estamos utilizando Eloquent para eliminar los registros -en vez del Facade DB– deberíamos ver que aún están en la base de datos:

Tabla de notas con eliminado lógico

Pero siempre que continuemos utilizando Eloquent para obtener los registros en nuestra aplicación, Laravel va a omitir las notas que hemos eliminado de forma lógica.

Si quieres aprender más sobre esta técnica te recomiendo ver la lección Crea una papelera en Laravel usando Soft Deletes de Eloquent ORM de nuestro Crea un Panel de Control con Laravel.

Material Relacionado

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Actualizar registros en Laravel 6