es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Doctrine 2: Construir una consulta dinámica iterando sobre una matriz de parámetros (condiciones AND)

Estoy tratando de averiguar cómo iterar correctamente en un array en una consulta personalizada del repositorio de Symfony 5.

Me explico. El usuario de la aplicación puede revisar varios valores en una página. Quiero mostrar objetos que coincidan con todos (pero no necesariamente solo) los valores marcados.

Fácilmente atrapo una matriz de los valores que envío a un controlador con Ajax, pero encuentro problemas con mi consulta personalizada.

Los valores coinciden con el parámetro “label” de una tabla (Tag) que está relacionada (ManyToMany) con la tabla (Flash) que selecciono con mi consulta.

Hasta ahora, he intentado muchas cosas, como:

public function getFlashesByTagsList($tags)
{
    $qb = $this->createQueryBuilder('f');
    $andX = $qb->expr()->andX();
    $qb->join('f.tags', 't');
    $qb->addSelect('t');
    foreach ($tags as $tag) {
        $andX->add(
            $qb->expr()->like('t.label', ':tag'),
            $qb->setParameter(':tag', '%' . $tag . '%')
        );
    }
    $qb->add('where', $andX);
    $qb->orderBy('f.id', 'DESC');
    $result = $qb->getQuery()->getResult();
    return $result;
}

Pero nada de lo que intenté funcionó. Si solo se envía un valor, obtengo todos los objetos que tienen este valor en sus etiquetas, pero tan pronto como hay más, solo obtengo los que coinciden con el último en el array $tags.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para iterar correctamente en un arreglo dentro de una consulta personalizada de un repositorio en Symfony 5, se puede usar el bucle foreach con una expresión andX para crear una consulta que coincida con todos los valores seleccionados.

    En tu código de ejemplo, estás uniendo la tabla tags con la tabla Flash y seleccionando la tabla tags. Luego, estás iterando a través del arreglo de valores seleccionados y agregando una expresión like a la expresión andX para cada uno.

    Sin embargo, estás sobrescribiendo el parámetro :tag para cada iteración del bucle, por lo que solo se está utilizando el último valor seleccionado. Para solucionar esto, se puede usar un nombre de parámetro único para cada iteración, como :tag1, :tag2, etc.

    Aquí está una versión actualizada de tu código que debería funcionar:

    public function getFlashesByTagsList($tags)
    {
        $qb = $this->createQueryBuilder('f');
        $andX = $qb->expr()->andX();
        $qb->join('f.tags', 't');
        $qb->addSelect('t');
        foreach($tags as $key => $tag) {
            $andX->add(
                $qb->expr()->like('t.label', ':tag'.$key),
                $qb->setParameter(':tag'.$key, '%'.$tag.'%')
            );
        }
        $qb->add('where', $andX);
        $qb->orderBy('f.id', 'DESC');
        $result = $qb->getQuery()->getResult();
        return $result;
    }
    

    Esto debería devolver objetos que coincidan con todos los valores seleccionados, en lugar del último.

Comments are closed.