Modelo: Validación automática
Las clases del modelo persistente aceptan la definición de restricciones sobre sus atributos y relaciones. Estas restricciones sirven para verificar automáticamente que los datos que se van a guardar en la base de datos son inválidos.Verificación automática de restricciones
La verificaci&ooacute;n de las restricciones se ejecuta al invocar a alguno de los siguientes métodos de PersistentObject:-
PersistentObject :: validate( $cascade = false ): boolean
Valida los valores de los campos contra las restricciones definidas en la clase. Retorna true si no hubieron errores de validación, false en caso contrario. Si se invoca con $cascade = true, también ejecuta "validate" sobre las instancias de clases asociadas. -
PersistentObject :: save(): boolean
Intenta guardar en la base de datos los datos de la instancia actual. Antes de guardar los datos, invoca a "validate" con $cascade = true. Retorna true si validaron todos los datos y se pudieron guardar, false si algún dato no valida (en este caso no guarda nada en la base de datos).
Nota: "save" detecta automáticamente si debe hacer INSERT o UPDATE. -
PersistentObject :: validateOnly( $attrs ): boolean
Este método es igual a validate, solo que valida los campos cuyos nombres estén presentes en el Array $attrs.
-
PersistentObject :: getErrors(): array<string, array<string>>
retorna por cada campo, un array con todos los errores generados para ese campo. -
PersistentObject :: getFieldErrors( attr: string ): array
retorna los errores generados para un campo específico. -
PersistentObject :: hasErrors(): boolean
retorna true si existen errores de validación, false en caso contrario. Obviamente debe invocarse luego de validar los datos, para poder ver si existen errores.
Ejemplo de definición de restricciones para distintos campos:
$this->addAttribute('nombre', Datatypes :: TEXT);
$this->addConstraints('nombre', array(
Constraint::minLength(1),
Constraint::maxLength(30),
Constraint::blank(false)
));
$this->addAttribute('edad', Datatypes :: INT_NUMBER);
$this->addConstraints('edad', array(
Constraint::between(10,100)
));
$this->addAttribute('email', Datatypes :: TEXT);
$this->addConstraints('email', array(
Constraint::email()
));
En el primer caso, el atributo nombre es de tipo TEXT, para este tipo de dato se pueden definir restricciones:
- minLength: restricción de tamaño mínimo para el string.
- maxLength: restricción de tamaño máximo para el string.
- blank: restricción que define si el string puede ser vacío o no.
- inList: restricción que define un conjunto de opciones posibles para el valor del atributo.
- nullable: indice si el atributo acepta valores nulos
El segundo atributo, edad, es un número entero (INT_NUMBER) al cual se puede definir las restricciones:
- min: indica el valor mínimo del atributo.
- max: indica el valor máximo del atributo.
- between: indica que el valor del atributo debe estar entre los valores especificados (combina las restricciones min y max).
- nullable: indice si el atributo acepta valores nulos
El atributo email es un string (tipo TEXT) que debe tener el formato válido de un email, por lo tanto se utiliza la restricción email para validar su formato.
Nota: la restricción maxLength para atributos de texto determina el tipo de la columna respectiva en la base de datos, por ejemplo, si se utiliza un maxLength de 100, la columna tendrá tipo VARCHAR(100), si se utiliza el valor 1000, la columna tendrá tipo TEXT.
Cuidado con las restricciones sobre atributos de una superclase
No se pueden declarar restricciones sobre atributos de una superclase si estos no fueron declarados antes,
o sea que es necesario inicializar la superclase antes de definir restricciones sobre sus atributos.
Ver ticket #22.
Consideraciones sobre nullable y blank
Se debe tener especial cuidado al definir restricciones nullable y blank en conjunto con otras restricciones. En el siguiente ejemplo se muestra la definición de una restricción nullable junto con inList:
$this->addAttribute('color', Datatypes :: TEXT);
$this->addConstraints('color',
array (
Constraint :: inList( array('blanco', 'negro', 'pardo') ),
Constraint :: nullable( true )
)
);
Si el atributo 'color' tiene valor NULL, al verificar las restricciones de la clase, primero se verifica la restricción nullable,
y si pasa la validación, no se verifica la restricción inList, devolviendo true. Esto se hace para evitar
inconsistencias entre la definición de nullable y blank con otras restricciones. Si no, en este ejemplo deberíamos incluir
el valor NULL en la lista de la restricción inList.
Aquí se pueden encontrar el código completo de una clase y sus restricciones.
Mensajes de error e i18n
Los mensajes de error generados al validar se adaptan autom´ticamente al idioma seleccionado (*). Las traducciones de los mensajes de error a distintos idiomas se definen en el script core.validation.Messages.Si una aplicación tiene disponible y seleccionado un idioma para el que no hay traducciones de errores especificados en core.validation.Messages, los mensajes de error se mostrarán como código (**). Para que se muestren mensajes de error en todos los idiomas que soporta una aplicación se puede:
- Agregar las traducciones a otros idiomas en el archivo core.validation.Messages
- Agregar las traducciones de los mensajes de error en el archivo de traducciones de la aplicación (ver documentación)
(**) Los códigos de error están definidos en la clase core.validation.ValidationMessage
