Para solventar este escollo es preferible crear un método en el modelo que genere en vez de un arreglo de objetos, un arreglo de hashes, en el cual solo se retornen los valores que nos interesan.
Volvamos al ejemplo con que trabajamos en el post anterior. Supongamos que queremos crear, en nuestro módulo personas, un reporte de tipo listado, donde aparezca el nombre de la persona, el país, estado y municipio donde reside. En la mayoría de las recomendaciones que encontramos en internet con respecto a estos casos indican que debemos crear método donde se defina el query con un string, parsearle los campos, y ejecutarlo. Veamos un ejemplo para entenderlo mejor:
<?php
/**
* Subclass for performing query and update operations on the 'persona' table.
*
*
*
* @package lib.model
*/
class PersonaPeer extends BasePersonaPeer
{
public static function getList()
{
$personas = array();
$con = Propel::getConnection();
$query = 'SELECT %s , %s, %s,
%s, %s
FROM %s
left join %s on %s = %s
left join %s on %s = %s
left join %s on %s = %s';
$query = sprintf($query, self::ID_PERSONA , self::NOM_PERSONA ,
PaisPeer::NOM_PAIS , EstadoPeer::NOM_ESTADO , MunicipioPeer::NOM_MUNICIPIO ,
self::TABLE_NAME,
PaisPeer::TABLE_NAME ,self::ID_PAIS , PaisPeer::ID_PAIS ,
EstadoPeer::TABLE_NAME , self::ID_ESTADO , EstadoPeer::ID_ESTADO ,
MunicipioPeer::TABLE_NAME , self::ID_MUNICIPIO , MunicipioPeer::ID_MUNICIPIO );
$stmt = $con->prepareStatement($query);
$rs = $stmt->executeQuery();
while ($rs->next())
{
$persona['id'] = $rs->getInt(1);
$persona['nombre'] = $rs->getString(2);
$persona['pais'] = $rs->getString(3);
$persona['estado'] = $rs->getString(4);
$persona['municipio'] = $rs->getString(5);
$personas[] = $persona;
}
return $personas;
}
}
Como vemos, este método del peer retorna un arreglo de hashes, cuya busqueda y armado es más rápido que armar un arreglo de objetos. Pero, que desventajas tiene?. La principal desventaja es que, a diferencias de otros métodos del peer, esto no nos permite pasarle condiciones de filtrado u ordenamiento a través de criteria. Para solventar esa deficiencia vamos a reescribir el mismo pero usando un objeto criteria, que se recibirá como parámetro:
<?php
/**
* Subclass for performing query and update operations on the 'persona' table.
*
*
*
* @package lib.model
*/
class PersonaPeer extends BasePersonaPeer
{
public static function getList(Criteria $criteria)
{
$personas = array();
// Clonamos el objeto, para evitar modificar el objeto original
$criteria = clone $criteria;
// Eliminanos las columnas de selección en caso de que esten definidas
$criteria->clearSelectColumns();
// Agregamos las columnas de las tablas que queremos recuperar
$criteria->addSelectColumn(self::ID_PERSONA );
$criteria->addSelectColumn(self::NOM_PERSONA );
$criteria->addSelectColumn(PaisPeer::NOM_PAIS );
$criteria->addSelectColumn(EstadoPeer::NOM_ESTADO );
$criteria->addSelectColumn(MunicipioPeer::NOM_MUNICIPIO );
// Agregamos los Joins entre las distintas tablas
$criteria->addJoin(self::ID_PAIS ,PaisPeer::ID_PAIS,Criteria::LEFT_JOIN );
$criteria->addJoin(self::ID_ESTADO , EstadoPeer::ID_ESTADO,Criteria::LEFT_JOIN );
$criteria->addJoin(self::ID_MUNICIPIO, MunicipioPeer::ID_MUNICIPIO );
//Recuperamos los registros y generamos el arreglo de hashes
$rs = self::doSelectRS($criteria);
while ($rs->next())
{
$persona['id'] = $rs->getInt(1);
$persona['nombre'] = $rs->getString(2);
$persona['pais'] = $rs->getString(3);
$persona['estado'] = $rs->getString(4);
$persona['municipio'] = $rs->getString(5);
$personas[] = $persona;
}
return $personas;
}
}
Aunque fue un poco más difícil de escribir, este método hace el mismo trabajo que el anterior, con la ventaja que recibe un objeto criteria, con lo cual podemos definir filtros por cualquier campo de las 4 tablas involucradas en la consulta ( Ejem: Obtener los datos de personas que viven en un estado específico, entre otros), lo cual hace este método más reusable. En un próximo post veremos como podemos utilizar este mismo método en la acción list autogenerada de nuestro módulo persona.