Laravel tiene muchas reglas de validación para cada ocasión (como se detallan aquí), pero aveces tenemos formularios con datos complejos que necesitamos aplicar cierta lógica para darlo como validos.
Por eso en este artículo vamos a ver como crear nuestras propias reglas de validación en Laravel de una forma muy fácil.
Creando nuestra Regla de Validación
Es muy fácil crear una regla de validación personalizada ya que Laravel nos provee un comando artisan para realizarlo.
Para este ejemplo vamos a suponer que queremos verificar que un usuario ingrese una contraseña con cierta cantidad de caracteres y caracteres especiales, para asegurarnos que tenga una contraseña fuerte.
Así que vamos a ejecutar el siguiente comando en la consola para crear nuestra regla personalizada:
php artisan make:rule ContrasenaFuerte
Laravel automáticamente creará un archivo en app/Rules/ContrasenaFuerte.php que se vea así:
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class ContrasenaFuerte implements Rule { /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { // } /** * Get the validation error message. * * @return string */ public function message() { return 'The validation error message.'; } }
Esta nueva clase, en principio, contiene dos métodos para que podamos editar.
El método passes()
recibe $attribute
, que es la key
del arreglo de reglas (en la utilización de la clase lo veremos en mas detalles), y $value
que contiene el valor en sí. Este método debe devolver true
o false
para indicar si paso o no la validación. Bastante intuitivo.
Para nuestro ejemplo, vamos a poner el siguiente código para el método passes()
.
public function passes($attribute, $value) { $uppercase = preg_match('@[A-Z]@', $value); $lowercase = preg_match('@[a-z]@', $value); $number = preg_match('@[0-9]@', $value); $specialChars = preg_match('@[^\w]@', $value); return $uppercase && $lowercase && $number && $specialChars; }
$value
contendrá la contraseña ingresada y con preg_match()
vamos verificando cada caso. Por ultimo, si alguno de dichos casos contiene false, la regla no se cumplirá.
Si la regla no se cumple, debemos mostrar un mensaje. Para esto utilizaremos el segundo método disponible message()
.
Mostrando mensaje de error para la regla personalizada
El método message() nos permite establecer el error que se mostrará cuando la regla no se cumpla. Tenemos disponible el comodín :attribute
que Laravel reemplazará por el nombre del atributo.
public function message() { return 'La :attribute debe tener al menos 8 caracteres y debe incluir al menos una letra mayúscula, un número y un carácter especial.'; }
Cómo utilizar la Regla Personalizada de Laravel
Por último veremos como se utiliza la clase de Laravel que acabamos de crear. Si estamos validando nuestro formulario en el controlador, debemos utilizar la clase de la regla personalizada de la siguiente forma:
use App\Rules\ContrasenaFuerte; class UserController extends Controller { // ... public function store(Request $request) { $this->validate($request, ['password' => ['required', new ContrasenaFuerte]]); // Más código... } // ... }
Como podemos ver, debemos utilizar los corchetes para crear una nueva instancia nuestra clase de regla personaliza.
No solo podemos utilizar la regla en el controlador, también podemos utilizarla en un FormRequest:
public function rules() { return [ 'password' => ['required', new ContrasenaFuerte] ]; }
Si no sabes que es un Form Request, te recomiendo que leas este artículo https://www.laraveltip.com/que-son-como-y-por-que-utilizar-los-form-request-de-laravel/.
Reglas de validación personalizadas con parámetros
También tenemos la posibilidad de enviarle datos adicionales a nuestra regla de validación, veamos cómo:
Primero, pasamos los datos adicionales a la clase.
$this->validate($request, ['password' => ['required', new ContrasenaFuerte(8, 24]]);
Y luego las capturamos en el constructor de la clase y establecemos propiedades para que podamos utilizar los valores en el método passes():
class ContrasenaFuerte implements Rule { private $min; private $max; public function __construct($min, $max) { $this->min = $min; $this->max = $max; } public function passes($attribute, $value) { $uppercase = preg_match('@[A-Z]@', $value); $lowercase = preg_match('@[a-z]@', $value); $number = preg_match('@[0-9]@', $value); $specialChars = preg_match('@[^\w]@', $value); return $uppercase && $lowercase && $number && $specialChars && $value >= $this->min && $value <= $this->max; } //(...) }
Beneficios de utilizar clases de Reglas Personalizadas
Como vimos, las clases de reglas personalizadas son muy útiles y fáciles de crear en Laravel. Además las podemos utilizarlas en infinitos proyectos. Y si, por algún motivo, el proyecto necesita una modificación especifica, solo debemos tocar esta clase.
Espero que les haya gustado el artículo y nos vemos en la próxima 😉🤙.
Muchas gracias excelente contenido como siempre no me pierdo ningún articulo para los entusiastas en Laravel, es impredible!
Gracias a vos Ariel por visitar la web. Saludos bro.
Hola como estás, esta muy bueno, pero no entiendo la implementación, pido disculpas, no entiendo el new Uppercase, no debería llamar a passes o a Contraseniasegura?
Si, mala mía. Ahí edité el post. Va ContrasenaFuerte. Gracias por la corrección. Saludos.
Excelente post como todos los de tu página, me han ayudado demasiado.
Como crear un Regla Personalizada que consulte a la base de datos??
Muchas gracias por tu comentario amigo. Si, puedes hacer una regla personalizada que consulte a la base de datos utilizando DB o un model, pero siempre ten en cuenta que passes() debe devolver verdadero o falso. Saludos.
Hola Gracias por tus aportes siempre me son utiles. Tengo una duda, quiero comprar dos campos q llegan del formulario, he creado la regla pero no se como pasar el segundo campo, para poder comprar.
Ejemplo:
regla:
public function passes($attribute, $value){
if( $value === ??? ){//aqui tendria q comprarlo con otro campo
return true;
}
return false;
}
Buenas noches, como seria para hacer lo mismo mendiante una peticion AJAX con token Api, me trata de redireccionar a una url y nos mostrar el mensaje en json
Muchas gracias, excelente contenido.
Muchas gracias Arturo.