Symfony - Duda con consulta en symfony 5

 
Vista:
Imágen de perfil de Reinier

Duda con consulta en symfony 5

Publicado por Reinier (2 intervenciones) el 28/07/2021 02:36:33
Saludos a todos, primero que nada, soy nuevo por aca y soy aprendiz de symfony para ello me he propuesto crear una aplicación web en symfony 5.18 la cual me ha servido como estudio, pero ahora me he tenido que enfrentar a una consulta un poco compleja. Les cuento: Tengo tres entidades que se relacionan entre ellas; Juego, criterio, usuario. Un juego puede tener varios criterios, y un criterio solo puede tener un juego. Cada criterio es emitido por un usuario. Por lo tanto, tengo definidas las siguientes relaciones en los modelos: Juego:

1
2
3
4
/**
 * @ORM\OneToMany(targetEntity=Criterio::class, mappedBy="juego", orphanRemoval=true)
 */
private $criterios;

Criterio:

1
2
3
4
5
6
7
8
9
10
/**
 * @ORM\ManyToOne(targetEntity=Juego::class, inversedBy="criterios")
 * @ORM\JoinColumn(nullable=false)
 */
private $juego;
/**
 * @ORM\ManyToOne(targetEntity=Usuario::class, inversedBy="criterios")
 * @ORM\JoinColumn(nullable=false)
 */
private $usuario;

Usuario:

1
2
3
4
/**
 * @ORM\OneToMany(targetEntity=Criterio::class, mappedBy="usuario", orphanRemoval=true)
 */
private $criterios;

Mi problema consiste en que tengo que hacer dos consultas que no me funcionan correctamente; necesito saber cuáles son los juegos en los cuales el usuario logueado no ha emitido un criterio, para ello he creado la siguiente consulta en el repositorio de juegos:

1
2
3
4
5
6
7
8
9
10
11
12
public function findPendingGamesByUser($user)
{
    return $this->getEntityManager()
        ->createQuery("
            SELECT j, c From App:Juego j
            LEFT JOIN j.criterios c
            WHERE c IS NULL
            OR c.usuario != :user
        ")
        ->setParameter('user', $user)
        ;
}

Esto me devuelve todos los juegos, en cambio si quito la línea: OR c.usuario != :user

Me devuelve los juegos que no tienen ningún criterio, y lo cual sería correcto, y si la modifico asi:

1
OR c.usuario == :user

Me devuelve los juegos que no tienen criterios, más los que el usuario logeado ya le ha emitido el criterio. No logro comprender porque no me funciona la consulta original. Si alguien pudiera arrojarme un poco de luz estaría agradecido.

DATOS DE EJEMPLO:

Usuarios:(total 2)

Pedro (Usuario logeado).

Juan

Criterios:(total 4)

Rust Legacy / Pedro

Rust Legacy / Juan

Hurtworld / Juan

Stalker / Pedro

Juegos:(Total 6)

Rust Legacy

Hurtworld

GTA

Call of Dutty

rainbow Six

Stalker

Resultado de la consulta:(total 5)

Rust Legacy.

Hurtworld.

GTA.

Call of Dutty.

rainbow Six.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Reinier

Duda con consulta en symfony 5

Publicado por Reinier (2 intervenciones) el 08/08/2021 23:19:13
Bueno finalmente he logrado obtener el resultado con la siguiente consulta:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public function findPendingGamesByUser($user)
    {
        return $this->getEntityManager()
            ->createQuery('
                SELECT j From App:Juego j
                WHERE j.id NOT IN (
                    SELECT jc.id From App:Criterio c
                    INNER JOIN c.usuario u
                    INNER JOIN c.juego jc
                    WHERE u = :user)
            ')
            ->setParameter('user', $user)
            ;
    }
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Duda con consulta en symfony 5

Publicado por Gonzo (3 intervenciones) el 28/09/2021 16:45:40
Buenas tardes Reinier,

Me alegro que hayas encontrado la solucion! Yo estoy intentando solucionar algo bastante parecido a lo tuyo y no se que debo hacer, soy bastante nuevo en symfony y aun me cuesta entender consultas mas complejas. Buscando por internet he dado con tu post!

Te comento a ver si puedes ayudarme:

Tengo una tabla que se llama "historico_garantias" en la cual tengo bastantes campos los cuales algunos estan relacionados con otras tablas.

Uno de esos campos que tiene historico_garantias es "usuario" el cual se relaciona con la tabla "Usuarios" que contiene la informacion de estos.

Relacion historico_garantias -> Usuarios:
1
2
3
4
5
6
7
8
9
/**
     * @var \Usuarios
     *
     * @ORM\ManyToOne(targetEntity="Usuarios")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="usuario", referencedColumnName="id")
     * })
     */
    private $usuario;

En esta tabla de usuarios esta el campo "delegacion" que simplemente es la localizacion este usuario, por lo que un usuario, tiene una delegacion asignada.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
 
namespace App\Repository;
 
use App\Entity\HistoricoGarantias;
use App\Entity\Usuarios;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
 
/**
 * @method HistoricoGarantias|null find($id, $lockMode = null, $lockVersion = null)
 * @method HistoricoGarantias|null findOneBy(array $criteria, array $orderBy = null)
 * @method HistoricoGarantias[]    findAll()
 * @method HistoricoGarantias[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
 
 
class HistoricoGarantiasRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, HistoricoGarantias::class);
    }
 
    /**
     * @return HistoricoGarantias[]
     */
    public function sinAbonos()
    {
        return $this->createQueryBuilder('g')
            ->andWhere('g.fechaAbonoCliente IS NULL AND g.abonoClienteRetenido=0 AND g.resolucionIncidenciaCliente!=3 ')
            ->orderBy('g.fechaEntradaMaterial', 'DESC')
            ->getQuery()
            ->getResult()
        ;
    }
}


Bien, lo que intento hacer es crear un filtro para que me muestre en pantalla una tabla con X registros del historico de garantias con X condiciones que tiene que cumplir, una de ellas es que los usuarios solo pueden ver las garantias que estan asociadas a su delegacion. Es decir, si el usuario pertenece a la delegacion de "valencia" solo podra ver los registros de las garantias que estan asociadas a "Valencia"


Como ves he añadido ya algunas de las condiciones que necesito pero no he tenido aun la necesidad de hacer JOINS entre tablas, y no encuentro nada que me aclare como hacerlo.

Como podria poner en esa consulta que por ejemplo:

delegacion=usuario.delegacion (en otra parte del codigo tengo esto app.user.delegacion, que me muestra la delegacion del usuario que se loguea, pero no se aplicarlo a lo que quiero)

Gracias y saludos!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar