Validaciones, Rutas Resource y Mensajes del Sistema
Validación de Datos
¿Qué es la validación y por qué es necesaria?
La validación es el proceso mediante el cual se verifica que los datos enviados por el usuario cumplen con unas reglas antes de ser almacenados en la base de datos.
Laravel ofrece un sistema de validación muy robusto, que nos permite validar datos tanto desde el controlador como mediante clases personalizadas.
Importante
Siempre debemos validar los datos antes de almacenarlos y antes de actualizarlos. Nunca debemos asumir que lo que llega del formulario es seguro o correcto.
Validar desde el controlador usando $request->validate()
En este caso vamos a utilizar un checkbox para marcar si la nota está completada o no. En el formulario, si el checkbox está marcado, se enviará done=on, y si no está marcado, no se enviará nada. Para evitar problemas con el on vamos a modificar la vista de creación y edición de notas para que el valor enviado sea 1 o nada en el caso de no estar marcado.
Checkbox en los formularios crear y editar
| create.blade.php y edit.blade.php | |
|---|---|
1 | |
Este método permite validar directamente dentro del método del controlador:
Función store()
1 2 3 4 5 6 7 8 9 10 11 12 | |
Cuando la validación falla, Laravel redirige automáticamente al formulario anterior. Una buena técnica es utilizar el método old() para recuperar el valor anterior del campos de manera que el usuario no tenga que volver a escribirlo.
1 | |
Haremos esto en todos los campos. Cuídado con los textarea que no tienen value y con los checkbox. Por ejemlo, para el checkbox:
1 | |
1.
Reglas comunes de validación:
| Regla | Descripción |
|---|---|
required |
El campo es obligatorio |
string |
Debe ser una cadena de texto |
min:n |
Longitud mínima de caracteres |
max:n |
Longitud máxima de caracteres |
date |
Debe ser una fecha válida |
boolean |
true/false, 0/1, "yes"/"no" |
nullable |
El campo puede estar vacío |
Crear una clase FormRequest personalizada
Comando:
php artisan make:request NoteRequest
Esto creará una clase en app/Http/Requests/NoteRequest.php
Método authorize()
Este método define si el usuario tiene permiso para hacer esta petición. Para este curso lo dejaremos en true:
Importante
Si este método devuelve false, la validación no se ejecutará y se lanzará un error 403 (Forbidden).
Autorizar la petición
1 2 3 4 | |
Método rules()
Ahora vamos a definir unas reglas de validación de ejmeplo para nuestro ejemplo de notas:
Ejemplo de reglas
1 2 3 4 5 6 7 8 9 | |
Uso en el controlador:
En el controlador, en lugar de usar Request $request, usaremos NoteRequest $request. Laravel se encargará de validar automáticamente los datos antes de ejecutar el método.
Almacenar una nota
1 2 3 4 5 6 7 | |
Antes de modificar el update()recordar que en la vista de edición el checkbox se envía como done=on o no se envía nada. Hacemos en esta vista lo mismo que en la de creación:
1 | |
Hacemos lo mismo para el método update():
Actualizar una nota
1 2 3 4 5 | |
Mostrar Errores de Validación
Mostrar errores en el formulario
Para el usuario es importante recibir feedback inmediato sobre los errores en el formulario. Laravel facilita esto con la variable $errors disponible en las vistas.
Puedes mostrar un error específico junto a cada campo:
1 2 3 4 | |
Resaltar campos con error (CSS)
También puedes añadir una clase CSS al campo si tiene error, para destacarlo visualmente según diseño de la aplicación:
<input name="title" class="@error('title') is-invalid @enderror">
Y luego en CSS puedes estilizar la clase .is-invalid.
Mostrar todos los errores juntos
Mostrar errores en la parte superior del formulario
1 2 3 4 5 6 7 8 9 | |
Modificar la vista de edición como lo hicimos en la de creación
La vista de creación debe haber quedado así:
Vista de creación
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 26 27 28 29 30 31 32 33 34 35 36 | |
también modificamos la vista del formulario de edición para mostrar los mensajes de error:
Vista de edición
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 26 27 28 29 30 31 32 33 34 35 36 37 | |
Algunos métodos interesantes de laravel que no hemos utilizado pero que se usan a menudo son:
| Clase | Método | Descripción |
|---|---|---|
Illuminate\Support\Facades\Validator |
make() |
Crear un validador |
Illuminate\Support\Facades\Validator |
fails() |
Verificar si la validación falló |
Illuminate\Support\Facades\Validator |
errors() |
Obtener los errores de validación |
Illuminate\Support\Facades\Validator |
validate() |
Validar y redirigir automáticamente |
Illuminate\Support\Facades\Request |
old() |
Obtener el valor anterior de un campo |
Illuminate\Support\Facades\Request |
flash() |
Guardar datos en la sesión para la siguiente petición |
Ahora vamos a probar a crear una nota con una descripción inferir a los 10 caracteres y veremos el mensaje de error.
Validación de datos
{ width=400px }
Ahora corregimos el error y vemos que la nota se crea correctamente. Además nos aparece un mensaje de éxito.
Validación de datos
{ width=400px }
Ahora podéis comprobar que:
- En la edición las validaciones y mensajes de éxito funcionan igual.
- El campo ´done´ funciona correctamente tanto en creación como en edición.
campo done
Si has seguido al pie de la letra las instrucciones, el campo done no va a funcionar. Al añadir la calse NoteRequest pedimos que el campo sea boolean pero a este punto está llegando un on cuando el checkbox está marcado, o nada cuando no lo está. Y por tanto no llegaremos nunca a que se ejecute el método store() o update(), que es donde estábamos manejando el valor del checkbox.
Solución
Necesitaos que cuando se valida el campo done, si está marcado llegue como true y si no está marcado como false. Ya que en la validación hemos especificado que debe ser un booleano. Para ello vamos a usar el método prepareForValidation() que nos permite modificar los datos antes de que se apliquen las reglas de validación.
Modificar datos antes de validar
Añadimos este método en la clase NoteRequest:
1 2 3 4 5 6 | |
De esta manera nos aseguramos que el campo done siempre llega como 1 o 0, y por tanto la validación funciona correctamente. Con esto ahora el campo done funciona correctamente.
prepareForValidation()
Este método es muy útil para modificar cualquier dato antes de que se aplique la validación. Por ejemplo, podríamos usarlo para formatear fechas, convertir cadenas a mayúsculas/minúsculas. No siempre la información que llega del formulario está en el formato que necesitamos para validar o almacenar. Y que no esté en el formato no significa que no sea válido. Pero la validación de laravel es estricta y debemos asegurarnos que los datos cumplen las reglas que hemos definido.
Traducir los mensajes de error
Laravel trae sus mensajes de error por defecto en inglés.
- Archivo por defecto:
resources/lang/en/validation.php - Puedes crear una versión en español copiando el contenido en:
resources/lang/es/validation.php - Activa el idioma por defecto en
config/app.php:
'locale' => 'es',
Mensajes de Éxito
Para mejorar la experiencia del usuario, es buena práctica mostrar mensajes de éxito o error después de operaciones como crear, actualizar o eliminar. PPara ello vamos a usar los mensajes flash, que permiten mandar un mensaje entre peticiones almacenándolo en la sesión.
Flash de sesión con with()
Este método permite guardar un mensaje en la sesión que se mostrará en la siguiente petición. Vamos a usarlo para mostrar un mensaje de éxito después de crear o actualizar o eliminar una nota.
En la función store() del controlador:
return redirect()->route('note.index')->with('success', 'Nota guardada correctamente.');
En la función update():
return redirect()->route('note.index')->with('success', 'Nota actualizada correctamente.');
destroy():
return redirect()->route('note.index')->with('danger', 'Nota eliminada correctamente.');
Mostrar el mensaje en la vista (por ejemplo, en layout):
Mostrar mensaje de éxito
1 2 3 4 5 6 7 8 9 10 | |
O incluirlo como partial:
_partials/messages.blade.php
Partial para mensajes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Y en el layout:
@include('_partials.messages')
Rutas Resource
¿Qué son?
Las rutas Route::resource() generan automáticamente todas las rutas necesarias para un CRUD completo. De esta manera nos ahorramos definir todas las rutas para todos los modelos.
Route::resource('note', NoteController::class);
Acciones generadas
| Ruta | Método | Acción |
|---|---|---|
| GET /note | index | Mostrar todas las notas |
| GET /note/create | create | Formulario para nueva nota |
| POST /note | store | Guardar nueva nota |
| GET /note/{note} | show | Mostrar una nota |
| GET /note/{note}/edit | edit | Formulario para editar |
| PUT/PATCH /note/{note} | update | Actualizar nota |
| DELETE /note/{note} | destroy | Eliminar nota |
Personalización
- Solo algunas rutas:
Route::resource('note', NoteController::class)->only(['index', 'show']);
- Excluir algunas:
Route::resource('note', NoteController::class)->except(['destroy']);
Ver rutas disponibles
php artisan route:list
Te muestra todas las rutas definidas, su método, URI y nombre.
Crear un controlador tipo resource
php artisan make:controller NoteController --resource
Este comando crea todos los métodos básicos (index, create, store, show, edit, update, destroy).
Conclusiones
- Validar datos es esencial para proteger la integridad de la base de datos.
- Los mensajes de error y éxito mejoran la experiencia del usuario.
- Las rutas resource simplifican la estructura del código.