Laravel 6

Laravel provee varios mecanismos para validar los datos provenientes de la petición del usuario. En esta lección veremos cómo agregar validación para campos requeridos y cómo mostrar errores de validación en nuestra vista.

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.

Estilos para los mensajes de error

Para ver los mensajes de error con estilos de CSS, descarga la nueva versión de la hoja de estilo y reemplázala en tu proyecto local. Si estás trabajando con Sass descarga el nuevo archivo SCSS, agrega @import "feedback"; a app.scss y recompila. También puedes ver nuestro Curso de Sass a fondo.

Agregar validación

Para prevenir que un usuario intente crear una nota sin título o sin contenido, agrega lo siguiente al principio de la ruta para crear posts:

Route::post('notas', function (Request $request) {
    $request->validate([
      'title' => 'required',
      'content' => 'required',
    ]);

    // El resto del código va aquí
})->name('notes.store');

Si ahora regresamos al formulario para crear notas e intentamos crear una nota sin completar el campo de título y/o contenido, podremos ver que Laravel nos manda de vuelta al formulario y -si revisamos el listado de notas o el administrador de base de datos- podemos ver que la nota no fue creada.

Esto demuestra que si la validación falla, Laravel no ejecutará el resto del código y creará una redirección a la ruta anterior. Sin embargo, la validación no está completa hasta que no proveemos feedback al usuario.

Mostrar errores de validación con Laravel

Cuando la validación falla, Laravel no solo redirige a la ruta anterior sino que envía la lista de errores de validación a la sesión. Además, estos errores estarán disponibles en la vista a través de la directiva @error, que usaremos tanto para agregar la clase field-error al campo como para mostrar el mensaje de error debajo del campo:

<!-- resources/views/add-note.blade.php -->

<input type="text" name="title" id="title" class="field-input @error field-error @enderror">
@error('title')
    <p class="error-message">{{ $message }}</p>
@enderror

Nota que en medio del par de directivas @error y @enderror podemos utilizar la variable {{ $message }} para obtener el mensaje de error del campo dado.

Si ahora volvemos a presionar el botón «Crear nota» sin completar el campo de título veremos el siguiente mensaje de error: «The title field is required.»

Lamentablemente este mensaje está en inglés y no en nuestro idioma, veamos cómo:

Traducir los mensajes de validación de Laravel

El idioma por defecto de una aplicación de Laravel es inglés, pero podemos cambiar esto muy fácilmente en el archivo config/app.php cambiando el valor de la llave locale de en a es:

<?php

return [
    'locale' => 'es',
];

Si hacemos esto y regresamos al navegador solo tenemos que presionar el botón «Crear nota» para darnos cuenta que… ¡El mensaje aún está en inglés!

Esto sucede porque por defecto Laravel no incluye las traducciones al español. Podemos ver los mensajes en inglés en resources/lang/en.

Afortunadamente existen varios paquetes como Laravel-lang que poseen las traducciones a español y otros idiomas. Podemos descargar el contenido de este paquete en un archivo .zip y luego copiar el directorio src/es en el directorio resources/lang de nuestro proyecto, de manera de que quede así:

Archivos de idioma de Laravel en español

Luego de hacer este cambio veremos los archivos en español ¡Excelente!

La razón por la cual -aún cambiando locale a es– seguíamos viendo los mensajes en inglés, es porque inglés está configurado como última opción si el mensaje solicitado no es encontrado en el idioma de la aplicación, esto está configurado en la llave fallback_locale de config/app.php.

Antes de continuar puedes agregar el mensaje para el campo content. También es posible:

Mostrar una lista de mensajes de error con Laravel

Podemos mostrar todos los mensajes de error que encontró el validador de una manera muy simple, agregando el siguiente código al principio de nuestro formulario:

<!-- resources/views/add-note.blade.php -->
@if ($errors->any())
    <div class="errors">
        <p><strong>Por favor corrige los siguientes errores<strong></p>
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

La variable $errors siempre está presente en la vista. Esta variable es una instancia de la clase Illuminate\Support\MessageBag. Con el método any() preguntamos si hay algún error en la vista. A través del método all() obtenemos todos los errores.

También podemos usar:  $errors->has('campo') para ver si un campo tiene errores de validación o $errors->first('campo') para obtener el primer mensaje de error de un campo, por ejemplo:

<!-- resources/views/add-note.blade.php -->

<input type="text" name="title" id="title" class="field-input {{ $errors->has('title') ? 'field-error' : '' }}">
@if ($errors->has('title'))
    <span class="error-message">{{ $errors->first('title') }}</span>
@endif

Conservar los datos del formulario luego de un error de validación

Cuando ocurra un error de validación, Laravel no solamente creará una redirección a la página anterior pasando los mensajes de errores, sino que también enviará los valores de los campos enviados por el usuario (válidos o no) de manera de que podamos mostrarlos en el formulario y evitar que se pierdan. Esto lo lograremos usando la función old y pasando como primer argumento el nombre de cada campo en cuestión:

<form>
   <input name="title" value="{{ old('title') }}">

   <textarea name="content">{{ old('content') }}</textarea>
</form>

Múltiples reglas de validación con Laravel

Un campo puede tener más de una regla de validación, por ejemplo, indiquemos que el título debe tener al menos 3 caracteres y debe ser único en la tabla de notas:

<?php

$request->validate([
    'title' => 'required|min:3|unique:notes,title',
    //...
]);

Nota cómo separamos cada regla de validación con una barra horizontal |. Además si la regla requiere un argumento lo especificamos con :. Múltiples argumentos se separan con ,. También podemos usar la sintaxis de arreglo:

<?php

$request->validate([
    'title' => ['required', 'min:3', 'unique:notes'],
    // unique:notes es suficiente si el nombre de la columna y el campo coinciden
    //...
]);

Incluso algunas reglas más complejas se pueden especificar a través de métodos o una combinación de cadenas y métodos dentro de un arreglo:

<?php

use Illuminate\Validation\Rule;

//...

$request->validate([
    'title' => ['required', 'min:3', Rule::unique('notes')],
    //...
]);

Esto es útil si la regla requiere de varios argumentos como veremos más adelante. También puedes darle un vistazo a la lección Nueva sintaxis para las reglas de validación: dimensions, exists, unique, in y not_in a partir de Laravel 5.3.

(No olvides importar la clase Illuminate\Validation\Rule).

Intenta crear notas con títulos de 2 caracteres o con títulos repetidos y verifica que no se haya creado la nota.

Únete a nuestra comunidad en Discord y comparte con los usuarios y autores de Styde, 100% gratis.

Únete hoy

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

Lección anterior Creación de registros con Laravel 6 Lección siguiente Controladores en Laravel 6