Desarrollo de un CRUD
Introducción a CRUD
El término CRUD corresponde a las operaciones básicas que se realizan en la mayoría de las aplicaciones que gestionan datos:
- Create (Crear): Insertar nuevos datos.
- Read (Leer): Consultar y visualizar datos.
- Update (Actualizar): Modificar datos existentes.
- Delete (Eliminar): Borrar datos.
En Laravel, la implementación de un CRUD completo nos permite comprender cómo los Modelos, Controladores y Vistas interactúan entre sí para ofrecer una experiencia de usuario completa.
Desarrollo de CRUDs
Dominar el desarrollo de CRUDs es básico para cualquier programador web, ya que casi todas las aplicaciones web tienen que manejar datos de algún tipo, y estas son las acciones fundamentales que se realizan sobre esos datos.
Además, este tema nos va a servir para aprender el funcionamiento de los formularios en Laravel.
Rutas Dinámicas y Controladores
Parámetros dinámicos en rutas
En Laravel, podemos definir rutas que aceptan parámetros dinámicos. Estos parámetros permiten que una misma ruta atienda solicitudes distintas según el valor proporcionado. Podemos permitirnos el símil de que el nombre de la ruta es el nombre de la función y los parámetros son los argumentos que recibe esa función. Por tanto nos va a permitir generar una respuesta dinámica en función de los parámetros que reciba.
Ejemplo sencillo:
| Ruta con Parámetro Dinámico | |
|---|---|
1 2 3 | |
En este caso, id es un parámetro dinámico. Si accedemos a http://localhost:8080/nota/5, Laravel mostrará: "Mostrando la nota con ID: 5".
Múltiples parámetros:
| Ruta con Múltiples Parámetros | |
|---|---|
1 2 3 | |
Importante
El orden de los parámetros en la URL debe coincidir exactamente con el orden de los parámetros en la función anónima o el controlador.
Crear un circuito MVC rápido para rutas dinámicas
Modelo: Vamos a utilizar una tabla notes con los campos:
id(entero, autoincremental)title(string)description(text)date(date)done(boolean)
Vamos a crear la migración de la nota y el controador:
Crear Migración y Modelo
php artisan make:migration create_notes_table
php artisan make:model Note
Podemos crearla migración y la nota con un solo comando:
Crear Modelo y Migración
php artisan make:model Note -m
Ahora vamos al archivo de migración database/migrations/xxxx_xx_xx_create_notes_table.php y añadimos los campos:
Migración
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Por último, ejecutamos la migración:
Ejecutar Migración
php artisan migrate
Si tenemos algún problema porque no hemos creado la base de datos desde 0, podemos eliminar las migraciones anteiores con:
Resetear Migraciones
php artisan migrate:reset
Modelo Note:
Ahora vamos a implementar el modelo Note. Vamos a definir los campos que se pueden asignar en masa y los que no:
Modelo
1 2 3 4 5 6 7 8 | |
$fillable: Define qué campos se pueden asignar en masa.$guarded: Define qué campos no se pueden asignar.
Controlador NoteController:
Crear Controlador
php artisan make:controller NoteController
Ahora codificamos el controlador app/Http/Controllers/NoteController.php:
método show, para mostrar un ID
public function show($id)
{
return view('notes.show', compact('id'));
}
Ruta asociada:
Ahora que ya tenemos el controlador y el método que manejará la ruta, y el modelo que se conectará con la base de datos, vamos a definir la ruta en routes/web.php:
Ruta con Parámetro Dinámico y Controlador
1 2 3 | |
Vista resources/views/notes/show.blade.php:
Por último nos queda crear la vista que mostrará la información de la nota con el ID recibido:
Vista show.blade.php
1 2 | |
Con esto, accediendo a /note/5 veremos "El ID de la nota es: 5".
imagen /note/5

función compact()
La función compact('variable') crea un array asociativo ['variable' => $variable] que puede ser pasado a la vista. Es una forma rápida y limpia de pasar datos. Sólo la puedo utilizar si el valor de la clave es el mismo que el nombre de la variable.
Parámetros opcionales y valores por defecto
Podemos definir parámetros opcionales añadiendo un signo de interrogación ?:
| Ruta con Parámetro Opcional | |
|---|---|
1 2 3 | |
- Si accedemos a
/saludo/Laura, veremos "Hola, Laura". - Si accedemos a
/saludo, veremos "Hola, Invitado".
Reglas para Parámetros Opcionales
- El parámetro opcional debe ser el último de la URL.
- Hay que asignar un valor por defecto en la función.
Importancia del orden de las rutas
Laravel evalúa las rutas en el orden en que se definen.
Ejemplo de conflicto:
| Orden de Rutas | |
|---|---|
1 2 | |
- Primero debe definirse
/nota/nuevaporque si no, Laravel intentará interpretarnuevacomo unid. - El orden correcto es siempre de rutas más específicas a más generales.
Consejo
Primero define todas las rutas fijas y luego las rutas con parámetros dinámicos.
Desarrollo del CRUD para notas
Listar todas las notas
Primero creamos la ruta y el método para listar todas las notas.
Ruta:
Ruta para Listar Notas
1 2 3 | |
Controlador:
método index, para listar todas las notas
use App\Models\Note;
public function index()
{
$notes = Note::all();
return view('notes.index', compact('notes'));
}
Explicación de @forelse vs @foreach:
@foreachse utiliza para recorrer elementos, pero no gestiona si el array está vacío.@forelsepermite recorrer elementos y además definir qué hacer si no hay elementos.
Ejemplo:
| Listado de Notas | |
|---|---|
1 2 3 4 5 | |
En el ejemplo anterior, si $notes está vacío, se mostrará "No hay notas disponibles."
Crear layout base en resources/views/layouts/app.blade.php:
Layout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Vista de Listado resources/views/notes/index.blade.php:
En este formulario vamos a adelantar algunas cosas que ampliaremos más adelante. Para poner el enlace a leminar una nota, vamos a utilizar un formulario con el método POST y la directiva @method('DELETE'). Esta directiva simula el método HTTP DELETE en formularios HTML (que solo permiten GET y POST). Más adelante explicaremos esto con más detalle. Hasta aquí nada especialmente llmativo. Pero también veréis que está la directiva @csrf. Esta directiva genera un campo oculto con un token que protege el formulario contra ataques CSRF (Cross-Site Request Forgery). Más adelante también explicaremos esto con más detalle. En laravel esta prtección es automática, pero hay que incluir la directiva @csrf en los formularios para que funcione correctamente.
Listado de Notas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Crear una Nueva Nota
Para poder crear una nota necesitamos tres cosas:
- Una ruta que muestre el formulario de creación,
/note/create. - Un método en el controlador que maneje esa ruta y muestre la vista con el formulario:
function create(). - Una vista que contenga el formulario de creación:
resources/views/notes/create.blade.php.
Ruta para formulario de creación:
Ruta para Crear Nota
Route::get('/note/create', [NoteController::class, 'create'])->name('note.create');
Controlador:
método create, para mostrar el formulario de creación
1 2 3 4 | |
Vista resources/views/notes/create.blade.php:
Formulario de Crear Nota
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Guardar la Nueva Nota
Al igual que en el caso anterior, para guardar la nota necesitamos dos cosas. Una ruta que maneje el envío del formulario y un método en el controlador que procese los datos y guarde la nota en la base de datos. Al final, redirigiremos a la lista de notas.
Ruta para guardar:
Ruta para Guardar Nota
1 | |
Controlador:
Para guardar la nota, podemos usar diferentes métodos. Aquí mostramos dos formas:
Guardar Nota
1 2 3 4 5 6 7 8 9 10 11 | |
O usando el método create:
Guardar Nota
1 2 3 4 5 | |
Explicaciones Adicionales:
@csrfprotege contra ataques CSRF (Cross-Site Request Forgery).$request->all()devuelve todos los datos enviados en el formulario.- Laravel valida automáticamente que el token CSRF esté presente. Si no lo está, lanzará un error.
¿Cómo funciona CSRF?
- Laravel genera un token único para cada sesión de usuario.
- Este token se incluye en cada formulario generado por Laravel.
- Cuando se envía el formulario, Laravel verifica que el token enviado coincida con el de la sesión.
- Si no coinciden, Laravel lanza un error 419 (Page Expired).
- Esto previene que un atacante envíe formularios en nombre del usuario sin su consentimiento.
Editar una Nota
Ruta para formulario de edición:
Ruta para Editar Nota
Route::get('/note/edit/{note}', [NoteController::class, 'edit'])->name('note.edit');
Controlador:
Tenemos varias formas de recibir el parámetro note. En esta primer recibimos el ID y buscamos la nota, para poder pasarla a la vista:
método edit, para mostrar el formulario de edición
1 2 3 4 5 | |
En esta segunda forma, recibimos el modelo Note. De esta manera es Laravel el que se encarga de buscar la nota. Cuando trabajamos con modelos, esta es la forma recomendada:
método edit, con inyección de modelo
1 2 3 4 | |
Vista resources/views/notes/edit.blade.php:
En este caso la ruta la hemos definido con el método PUT. Este método es el que se utiliza para actualizar los datos de un recurso existente. Pero ¿cómo hacerlo si las opciones de form solo permiten GET y POST?. Laravel nos ofrece una solución sencilla: la directiva @method('PUT'). Esta directiva simula el método PUT en formularios HTML. Esta directiva debe estar dentro del formulario y antes de los inputs.
| Editar Nota | |
|---|---|
1 2 3 4 5 | |
Con este formato el formulario se enviará como un PUT, aunque el método del formulario sea POST.
Formulario de Editar Nota
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
@method('PUT') simula el método HTTP PUT en formularios HTML (que solo permiten GET y POST).
Actualizar la Nota
Ruta para actualizar:
Ruta para Actualizar Nota
1 | |
Controlador:
En este caso también tenemos dos formas de recibir el parámetro Note $note. En esta primer caso recibimos la nota y laravel por inyección de modelo la busca por nosotros y en el segundo caso recibimos el ID y buscamos la nota nosotros.
método update, con inyección de modelo
1 2 3 4 5 | |
método update, buscando por ID
1 2 3 4 5 6 | |
Mostrar una Nota Individual
Ruta para mostrar:
Ruta para Mostrar Nota
Route::get('/note/show/{note}', [NoteController::class, 'show'])->name('note.show');
Controlador:
En este caso también tenemos dos formas de recibir el parámetro Note $note. En esta primer caso recibimos la nota y laravel por inyección de modelo la busca por nosotros y en el segundo caso recibimos el ID y buscamos la nota nosotros.
método show, buscando por ID
1 2 3 4 5 | |
método show, para mostrar una nota individual
1 2 3 4 | |
Vista resources/views/notes/show.blade.php actualizada:
Mostrar Nota
1 2 3 4 5 6 7 8 9 10 11 | |
Eliminar una Nota
Ruta para eliminar:
Ruta para Eliminar Nota
Route::delete('/note/destroy/{note}', [NoteController::class, 'destroy'])->name('note.destroy');
Controlador:
Como en los casos anteriores, tenemos dos formas de recibir el parámetro Note $note. En esta primer caso recibimos la nota y laravel por inyección de modelo la busca por nosotros y en el segundo caso recibimos el ID y buscamos la nota nosotros.
método destroy, buscando por ID
1 2 3 4 5 6 | |
método destroy, para eliminar una nota
1 2 3 4 5 | |
- El método
delete()elimina el registro de la base de datos.
Prueba completa del CRUD
Ahora vamos probar todas las funcionalidades del CRUD:
Aspecto del ejemplo
Al no utilizar nada de CSS, el aspecto es muy básico. En un proyecto real, se debería aplicar estilos CSS para mejorar la apariencia y usabilidad.
-
Listar Notas: Accede a la ruta
/para ver el listado de notas.imagen /

-
Crear Nota: Haz clic en "Crear Nota", rellena el formulario y envíalo.
Al hacer click en "Crear Nota" se accede a
/note/create:imagen /note/create

Una vez rellenado el formulario lo enviamos al servidor (ruta
/note/store) y volvemos al listado de notas.imagen /

Podemos ver la nota creada y como aparecen los enlaces para editar y eliminar.
-
Editar Nota: Haz clic en "Editar" junto a una nota, modifica los datos y envía el formulario.
Al hacer click en "Editar" se accede a
/note/edit/{id}:imagen /note/edit/1

Una vez modificado el formulario lo enviamos al servidor (ruta
/note/update/{id}) que actualiza la nota y nos redirecciona al listado de notas.imagen /

-
Mostrar Nota: Haz clic en el título de una nota para ver sus detalles.
Al hacer click en el título de una nota se accede a
/note/show/{id}:imagen /

imagen /note/show/1

Una vez vista pulsamos volver y nos redirecciona al listado de notas.
-
Eliminar Nota: Haz clic en "Eliminar" junto a una nota. Al hacer click en "Eliminar" se envía un formulario con método
DELETEa la ruta/note/destroy/{id}que elimina la nota y nos redirecciona al listado de notas.Confirmación de Eliminación
En un proyecto real, es recomendable añadir una confirmación antes de eliminar una nota para evitar eliminaciones accidentales.
imagen /

Tipado en los métodos del controlador
Ejemplo de tipado correcto:
1 2 3 4 5 | |
- Tipar los parámetros mejora la legibilidad y control de errores.
- Tipar el tipo de retorno ayuda a Laravel a validar internamente las respuestas.
Tipos comunes de retorno
Viewpara devolver vistas.use Illuminate\View\ViewRedirectResponsepara redirecciones.use Illuminate\Http\RedirectResponseJsonResponsepara APIs.use Illuminate\Http\JsonResponse