Symfony propel: usar funciones en el objeto Criteria

Criteria es el objeto que permite definir los criterios de selección de resultados en sistemas que emplean Propel como ORM. Propel y Doctrine son dos plataformas de mapeo de resultados SQL a clases empleados por Symfony. Este post se centra en el uso de Propel y describo como emplear funciones SQL propias en el objeto Criteria.

Imagina que tenemos una tabla llamada producto con dos campos:

  • id
  • nombre

En el modelo de clases generado por Symfony tendremos una clase llamada ProductoPeer que es la encargada de realizar los accesos a base de datos. Para realizar las consultas hemos de construir un objeto Criteria que contiene las características de los datos que deseamos seleccionar. En algunas ocasiones es útil emplear funciones que hemos escrito en base de datos, como por ejemplo, una función que dado un id de producto nos devuelve el número de veces que se ha consultado en nuestra web. El código lógico sería el siguiente:

$criteria = new Criteria();

$criteria->addAsColumn(‘consultas’, ‘getConsultasProducto(‘.ProductoPeer::ID.’)’);
$criteria->add(ProductoPeer::ID, $productoId);
ProductoPeer::doSelect($criteria);

getConsultasProducto es una función de base de datos que devuelve el número de consultas.

Si lanzamos la aplicación dará un error indicando que ProductoPeer no puede encontrar el campo con la clave primaria. Para evitar esto usamos lo siguiente:

$criteria = new Criteria();
$criteria->clearSelectColumns();
$criteria->addSelectColumn(self::ID);
$criteria->addSelectColumn(self::NOMBRE);
$criteria->addAsColumn('consultas', 'getConsultasProducto('.ProductoPeer::ID.')');
$criteria->add(ProductoPeer::ID, $productoId);
ProductoPeer::doSelect($criteria);

Lo nuevo con respecto al código inicial es que se resetean los campos que estarán en la select y se añaden en el mismo orden en el que están declarados en config/schema.yml del proyecto. Gracias a esto, podemos ordenar los resultados por el número de consultas del producto:

$criteria->addDescendingOrderByColumn($criteria->getColumnForAs('consultas'));

Espero que sea de utilidad. Saludos.

2 comentarios
  1. Diego Baulde dijo:

    Muy buen aporte Victor! Es dificil encontrar sugerencias como la tuya. Te quiero hacer una pregunta si puede ser, tengo un proyecto con una tabla en la cual una columna “numero” va incrementandose, pero llegado el primer día del año tiene que volver a 1 nuevamente. Yo he logrado esta función incremental de la siguiente manera:

    public static function getSiguiente()
    {

    $c = new Criteria();
    $c -> addDescendingOrderByColumn(self::NUMERO);
    $res = self::doSelectOne($c);

    if($res === NULL)
    return $res = 1;
    else
    return $res->getNumero() + 1;
    }

    Ahora faltaría la parte del “reseteo”, se te ocurre alguna forma u otra forma. Intente una forma muy rústica que era insertar una fila con valor NULL, pero sigue sumado desde el valor más alto.
    Desde ya muchas gracias
    Diego

  2. Víctor dijo:

    Si la columna no es autoincremental, como parece que dices, solo faltaría incluir una condición que compruebe si se ha llegado al nuevo año y en ese caso devolver uno.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: