Características del ORM de CakePHP 3.0

Una de las novedades más importantes de la rama 3.x de CakePHP ha sido la incorporación de un nuevo ORM (Object-Relational Mapping ). Este nuevo motor reemplazare incorpora varias funciones mejoradas que permiten eliminar cierta redundancia y aumentar la eficiencia en la gestión de los datos. En este artículos nos centraremos en los tres aspectos más importantes y novedosos:

1. afterFind y campos virtuales

Los programadores que utilizaban las versiones anteriores de CakePHP tenían que usar afterFind y campos virtuales para generar nuevas propiedades de datos. En la versión 3.0 esto ya no es necesario ya que ha sido eliminado en favor del uso de entidades que son más potentes y fáciles de utilizar. Con el nuevo objeto Entity las propiedades se pueden generar de forma instantánea y de una manera mucho más natural como puedes observar en el siguiente ejemplo:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Usuario extends Entity
{

    protected function _getNombreCompleto()
    {
        return $this->_properties['nombre'] . '  ' .
            $this->_properties['apellidos'];
    }

}
        

Al definir los métodos de acceso se generan propiedades / campos que en realidad no existen. Por ejemplo, si la tabla de usuarios tiene un campo de nombre y otro de apellido, se puede crear un método para obtener el nombre completo. El nombre de la propiedad será la versión en minúscula y subrayada del método.

Puede acceder a los campos virtuales como si existieran en la entidad, pero hay que tener en cuenta que no se pueden utilizar en las búsquedas.

echo $usuario->nombre_competo;
    

Una vez que se ha definido el un código similar al anterior, se puede acceder fácilmente con $usuario->nombre_competo. Puede crear conjuntos de datos agregados a partir de sus resultados. Ten en cuenta también que aunque los campos virtuales ya no constituyen una características explícita del ORM, todavía se puede obtener el mismo resultado utilizando objetos de consulta y expresiones que sean más potentes y flexibles.

2. Definición de asociaciones

Otra característica extremadamente importante introducida en CakePHP 3.0 es el uso de métodos para crear asociaciones. En lugar de definir asociaciones en las propiedades como $ belongsTo y $ hasMany, en el nuevo ORM se utilizan métodos que pasan por alto las muchas limitaciones inherentes de las definiciones de clase permitiendo sólo una forma de definir asociaciones. Además, la misma API maneja el método "initialize" y todas las demás partes del código de la aplicación al manipular asociaciones. Esto es mucho más eficiente y mejora significativamente la productividad. A continuación un fragmento de código que ilustra perfectamente como definir asociaciones entre modelos.

class ArticulosTable extends Table
{

   public function initialize(array $config)
   {
       $this->belongsTo('Autores');

       $this->hasMany('Comentarios', [
           'className' => 'Comentarios,
           'conditions' => ['aprobado' => true]
       ]);

       $this->hasMany('ComentariosNoAprobados', [
           'className' => 'Comentarios',
           'conditions' => ['aprobado => false],
           'propertyName' => 'comentarios_noaprobados'
       ]);
   }
}
    

Además del uso de métodos para crear asociaciones, es renombrado el excesivamente largo "hasAndBelongsToMany" tipo de asociación a un "belongsToMany".

Otra nueva característica que se ha dotado con el nuevo ORM es la capacidad de crear clases de asociaciones personalizadas, la cual permitirá a los desarrolladores crear tipos de relaciones que no cumplan con los requisitos standard.

3. Reglas de Validación

La validación juega un papel importantísimo en la mayoría de los desarrollos de software. Si se quiere contribuir a la productividad general del ciclo de desarrollo, la forma en que se definen y utilizan las validaciones debe de ser sencilla y muy fácil de utilizar. La solución que se presenta en la versión 3.x de CakePHP es elegante y resuelve muchos de los problemas que se arrastraban las versiones anteriores. Esto se consigue con el uso del objeto "Validator" que a patir de ahora se utilizará para la generación de las reglas de validación. Con esta nueva característica la generación compleja de conjuntos de reglas se ha convertido en una tarea muy sencilla. A continuación un ejemplo:

class UsuariosTable extends Table
{

    public function validationConfirmaPassword(Validator $validator)
    {
        $validator
            ->requirePresence('confirmacion_password', 'create')
            ->notEmpty('confirmacion_password');

        $validator->add('password', 'custom', [
            'rule' => function ($value, $context) {
                $confirmacion = Hash::get($context, 'data.confirmacion_password');
                if (!is_null($confirmacion) && $value != $confirmacion) {
                    return false;
                }
                return true;
            },
            'message' => __d('Usuarios', 'El password no coincide con el valor del campo de confirmación. Inténtelo de nuevo'),
            'on' => ['create', 'update'],
            'allowEmpty' => false
        ]);

        return $validator;
    }

}
        

La validación "ConfimaPassword" sólo será aplicada si esta es pasada en el parámetro "validate".

$usuario = $this->Usuarios->patchEntity($usuario, $this->request->data(), ['validate' => 'ConfirmaPassword']);
        

Lo que es digno de mención sobre el segmento de código anterior es la capacidad de definir tantos métodos de validación como sea necesario. Observa cómo cada método debe ser prefijado con "validation" y debe estar estructurado para aceptar un argumento $validator.

A disfrutar de estas nuevas características del nuevo ORM que nos permitirán escribir código mucho más flexible y potente.

Volver al índice del blog