IIC2513-2021-2 / project

Repositorio oficial para el proyecto del curso IIC2513, período 2021-2
32 stars 1 forks source link

Sequelize Eager Loading - Cargar solo tabla de unión #39

Open benjavicente opened 2 years ago

benjavicente commented 2 years ago

Hola! 👋

¿Cómo se puede consultar los ids de una tabla de unión sin hacer una unión con las entidades?

Por ejemplo, con este esquema:

 Persona <-tiene-> Auto
    |                |
    \  <-viajó en->  /

Con el id de una persona, me gustaría buscar todo vehículo que tiene la persona y una lista de ids de los pasajeros, si cargar el objeto de cada pasajero.

Lo único que he encontrado es lo contrario a lo que quiero 😅

sivicencio commented 2 years ago

Hola. Deberías poder lograr lo que planteas juntando nested eager loading con especificar atributos en la asociación (específicamente la parte que dice options.include[].attributes):

await ctx.orm.Persona.findByPk(personaId, {
  include: {
    model: ctx.orm.Auto,
    include: {
      // Nested model with specific attributes
    }
  }
});

Este artículo también puede ayudarte si con lo anterior no es suficiente para lo que estás buscando.

benjavicente commented 2 years ago

¿En ese caso la tabla intermediaria tendría que ser un modelo?

await ctx.orm.Persona.findByPk(personaId, {
  include: {
    model: 'Auto',
    include: {
      model: 'PasajeroAuto',
    }
  }
});

Edit: mi meta sería evitar joins innecesarios en la consulta, el SQL que busco realizar es algo así:

SELECT AutosDelUsuario.*, pasajero.id
  FROM (
  SELECT Auto.*
    FROM Auto, DuenioAuto
   WHERE Auto.id = DuenioAuto.autoId
     AND DuenioAuto.usuarioId = :idDelUsuario
) AS AutosDelUsuario, PasajeroAuto
  WHERE AutosDelUsuario.id = PasajeroAuto.autoId

para que quede un objeto de más o menos siguiente formato:

[
  {
     id: 1,
     color: "azul",
     patente: "XYZ",
     idPasajeros: [4, 49, 73]
  }
]

Pero si no se puede hacer "limpiamente" con Sequelize, me quedo con lo más sencillo nomás.

sivicencio commented 2 years ago

No es necesario que la tabla intermedia sea un modelo. Si especificas model dentro de include como string (y no con ctx.orm.myModel) el valor debiese corresponder al nombre de la tabla directamente.

Sobre el caso particular que necesitas, no sé realmente si se puede llegar a algo como lo que necesitas con métodos de Sequelize solamente. Tal vez podrías llegar a algo cercano como:

[
  {
     id: 1,
     color: "azul",
     patente: "XYZ",
     pasajeros: [
       {
         id: 4,
       },
       {
         id: 49,
       },
       {
         id: 73,
       }
     ],
  }
]

Si eso no te sirve, o derechamente no puedes llegar a algo así, entonces una raw query sería la opción.