Hola, estoy haciendo una consulta que obtiene los artículos y el número de comentarios que tiene cada artículo de esta forma:
public function findArticulosAndNComentarios() { $em = $this->getEntityManager(); $dql = 'SELECT a AS articulo, COUNT(c.id) AS nComentarios FROM MiniBlogBundle:Articulo a LEFT JOIN MiniBlogBundle:Comentario c WHERE c.articulo = a.id GROUP BY a ORDER BY a.fechaCreacion'; $query = $em->createQuery($dql); return $query->getResult(); }
Y en twig lo muestro de esta forma:
{% for fila in articulos %} {% set articulo = fila['articulo'] %} {% set comentarios = fila['nComentarios'] %} {% endfor %}
Como veis en la consulta he tenido que poner un nombre para artículos para así no tener que poner en twig fila['0']
. Mi pregunta es más bien si esta es la forma que hay de hacer esto o existe otra manera más clara y mejor.
Un saludo.
Respuestas
Tal y como se explica en la sección "Pure and Mixed Results" del manual de Doctrine, existen dos tipos de resultados para las consultas DQL: resultados puros y resultados mixtos.
Los resultados puros son los que obtienes con la mayoría de consultas DQL y te permiten crear plantillas muy concisas, ya que la estructura de los resultados es la siguiente:
array [0] => Objeto [1] => Objeto [2] => Objeto ...
Si en la consultas añades un valor agregado (como en tu caso por ejemplo COUNT(c.id)
) o un valor que no pertenezca a la entidad que estás consultando, entonces obtienes resultados mixtos, que tienen la siguiente estructura:
array [0] [0] => Objeto [1] => Valor agregado [1] [0] => Objeto [1] => Valor agregado [2] [0] => Objeto [1] => Valor agregado ...
Si realmente quieres simplificar tus plantillas, puedes reeemplazar el método getResult()
de la consulta por getScalarResult()
. Si lo haces, la estructura de los resultados será la siguiente:
array [0] array [a_id] => ... [a_titulo] => ... [a_contenido] => ... ... [nComentarios] => ... [1] array [a_id] => ... [a_titulo] => ... [a_contenido] => ... ... [nComentarios] => ... ...
Ten en cuenta que si utilizas el método getScalarResult()
, lo que obtienes son simples arrays y no objetos hidratados, por lo que no podrás utilizar el lazy loading de Doctrine2 y muchas otras de sus características más interesantes.
@javiereguiluz
Hola, gracias por tu gran respuesta. Por lo que veo entonces, la mejor opción es como lo he hecho ya que si no, pierdo funciones de Doctrine.
Un saludo
@AlbertoVioque