6.4 Validaciones, Rutas Resource y Mensajes del Sistema
6.4.1 Validación de Datos
6.4.1.1 ¿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.
6.4.1.2 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.
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 |
6.4.1.3 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:
1 2 3 4 | |
Método rules()
Define las reglas de validación:
Ejemplo de reglas
1 2 3 4 5 6 7 8 9 | |
Uso en el controlador:
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 | |
6.4.2 Mostrar Errores de Validación
6.4.2.1 Mostrar errores en el formulario
Puedes mostrar un error específico junto a cada campo:
1 2 3 4 | |
6.4.2.2 Resaltar campos con error (CSS)
Puedes aplicar clases para marcar campos con error:
<input name="title" class="@error('title') is-invalid @enderror">
Y luego en CSS puedes estilizar .is-invalid.
6.4.2.3 Mostrar todos los errores juntos
Mostrar errores en la parte superior del formulario
1 2 3 4 5 6 7 8 9 | |
6.4.2.4 Modificar la vista de edición como lo hicimos en la de creación
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 |
6.4.2.4 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',
6.4.3 Mensajes de Éxito
6.4.3.1 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.');
6.4.3.2 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')
6.4.4 Rutas Resource
6.4.4.1 ¿Qué son?
Las rutas Route::resource() generan automáticamente todas las rutas necesarias para un CRUD completo.
Route::resource('note', NoteController::class);
6.4.4.2 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 |
6.4.4.3 Personalización
- Solo algunas rutas:
Route::resource('note', NoteController::class)->only(['index', 'show']);
- Excluir algunas:
Route::resource('note', NoteController::class)->except(['destroy']);
6.4.4.4 Ver rutas disponibles
php artisan route:list
Te muestra todas las rutas definidas, su método, URI y nombre.
6.4.4.5 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).
6.4.5 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.
Ejercicio para el Tema 9: Validaciones y Mensajes para Productos
Enunciado
Objetivo: Mejorar el CRUD de productos implementando validaciones, gestión de errores y mensajes de éxito.
-
Crea una clase FormRequest para productos:
-
Define las reglas de validación:
name: requerido, mínimo 3 caracteres.description: requerido, mínimo 10 caracteres.price: requerido, numérico, mayor que 0.stock: requerido, entero, mínimo 0.
-
Utiliza StoreProductRequest en los métodos
store()yupdate()del controlador. -
Gestiona errores en los formularios:
- Mostrar errores junto a los inputs con
@error. -
Mostrar una lista general de errores arriba del formulario si existen.
-
Mostrar mensaje de éxito:
- Cuando un producto se cree, actualice o elimine correctamente.
- Usa
session()->flash('success', 'Producto creado correctamente.') -
Muestra los mensajes en el layout usando un partial
partials/alert.blade.php. -
Usa el comando:
php artisan route:list
Ejercicio Tema: Solución
Ver Solución Tema 9
Ver Solución Tema 9
// Crear el FormRequest
php artisan make:request StoreProductRequest
// app/Http/Requests/StoreProductRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreProductRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|min:3|max:255',
'description' => 'required|string|min:10',
'price' => 'required|numeric|min:0.01',
'stock' => 'required|integer|min:0',
];
}
}
// ProductController.php
use App\Http\Requests\StoreProductRequest;
public function store(StoreProductRequest $request)
{
Product::create($request->validated());
return redirect()->route('product.index')->with('success', 'Producto creado correctamente.');
}
public function update(StoreProductRequest $request, Product $product)
{
$product->update($request->validated());
return redirect()->route('product.index')->with('success', 'Producto actualizado correctamente.');
}
public function destroy(Product $product)
{
$product->delete();
return redirect()->route('product.index')->with('danger', 'Producto eliminado correctamente.');
}
<!-- resources/views/products/create.blade.php o edit.blade.php -->
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if (session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@if (session('danger'))
<div class="alert alert-success">
{{ session('danger') }}
</div>
@endif
// Verificar rutas
php artisan route:list