Contenido del curso
Database
- 3

Instalación de Docker en Windows, macOS y Ubuntu
01:35 min - 4

Configuración de Postgres en Docker Compose
09:18 min - 5

Conexión a Postgres en Docker: Terminal y PgAdmin
15:16 min - 6

Conexión de NestJS a Postgres con Node Postgres
07:28 min - 7

Inyección de Dependencias en NETJS: Conexión a PostgreSQL
10:49 min - 8

Conexión a Bases de Datos con Variables de Entorno en Node.js
13:49 min
TypeORM
- 9

Implementación de TypeORM con NestJS en Proyectos Node.js
09:14 min - 10

Creación de Entidades en ORM para Tiendas Virtuales
07:46 min - 11

Implementación del Patrón Repository en NestJS con TypeORM
13:31 min - 12

Operaciones CRUD en ProductService usando TypeORM y Postgres
13:35 min - 13

Cambio de Postgres a MySQL en Docker para CRUD de Productos
17:28 min
Migraciones
Relaciones
- 18

Relaciones 1 a 1 en Bases de Datos con TimeORM
18:58 min - 19

Manipulación de Relaciones Uno a Uno en Controladores y Servicios
10:28 min - 20

Relaciones Uno a Muchos en Bases de Datos con TypeORM
10:36 min - 21

Gestión de Relaciones Uno a Muchos en Controladores de API
10:27 min - 22

Relaciones Muchos a Muchos en Time1M: Creación y Manejo Práctico
08:38 min - 23

Manipulación de Relaciones Muchos a Muchos en Controladores
Viendo ahora - 24

Manipulación de Relaciones Muchos a Muchos con TimeORM en JavaScript
19:08 min - 25

Relaciones Muchos a Muchos con Campos Agregados en TimeWareM
16:40 min - 26

CRUD de órdenes de compra y gestión de ítems en NestJS
30:07 min
Consultas
- 27

Paginación de Productos con Limit y Offset en Controladores API
10:37 min - 28

Filtrado de Precios con Rango Usando Between en Time Wareham
10:16 min - 29

Indexación de Parámetros en Bases de Datos: Uso y Precauciones
02:54 min - 30

Buenas prácticas de nombramiento en JavaScript y bases de datos
17:52 min - 31

Serialización y Transformación de Datos en APIs con ClassTransformer
16:55 min
Migración a NestJS 9 y TypeORM 0.3
Próximos pasos
Manipulación de Relaciones Muchos a Muchos en Controladores
Resumen
Trabajar con relaciones muchos a muchos va más allá de definir entidades: el verdadero reto está en manipular esas relaciones desde los controladores y servicios. Aquí se aborda paso a paso cómo recibir un array de IDs desde el payload, resolver las categorías asociadas y asignarlas correctamente a un producto usando TypeORM en NestJS.
¿Cómo preparar el DTO para recibir múltiples categorías?
El punto de partida es el Data Transfer Object (DTO). Cuando un producto puede pertenecer a varias categorías, necesitamos un campo que reciba un array de IDs [01:00].
Dentro del CreateProductDTO se agrega un campo categoriesIds con las siguientes validaciones:
- Debe ser de solo lectura (read-only).
- No puede estar vacío.
- Debe ser un array, validado con el decorador
@IsArray()de class-validator [01:30].
Este DTO viaja desde el payload al controlador, y del controlador al servicio, donde finalmente se resuelve la relación.
¿Por qué inyectar el repositorio directamente en lugar de usar el servicio?
Una decisión arquitectónica importante surge al resolver las categorías. El servicio de categorías tiene métodos como findAll, findOne, create y update, pero no tiene un método para buscar múltiples IDs a la vez [02:30].
TypeORM ofrece el método findByIds en el repositorio, que permite enviar un array de IDs y recibir todos los modelos correspondientes en una sola consulta [03:15]. En lugar de crear una abstracción innecesaria en el servicio de categorías, se inyecta directamente el repositorio:
typescript @InjectRepository(Category) private categoryRepo: Repository<Category>
Con esto, la resolución es directa:
typescript if (data.categoriesIds) { const categories = await this.categoryRepo.findByIds(data.categoriesIds); newProduct.categories = categories; }
Se busca el grupo de categorías, se asigna al producto y con save se persiste la relación [03:45].
¿Qué problema genera reutilizar el servicio de marcas?
Al crear un producto, se reutilizaba brandService.findOne para resolver la marca. Sin embargo, ese método incluía la relación products como parte del query [06:00]. El resultado era que al crear un producto, la respuesta devolvía la marca con todo su array de productos asociados, lo cual genera un payload innecesariamente pesado.
Esto representa un problema de rendimiento: se envía información que el usuario no necesita, consumiendo ancho de banda y recursos [07:30]. La solución fue inyectar también el repositorio de marcas directamente:
typescript @InjectRepository(Brand) private brandRepo: Repository<Brand>
Al usar brandRepo.findOne, se obtiene únicamente la entidad sin relaciones extras, a menos que se especifiquen explícitamente.
¿Cuándo conviene resolver relaciones en el detalle del producto?
No siempre es necesario traer todas las relaciones. En el listado general de productos (GET /products), probablemente no necesites el array completo de categorías. Pero en el detalle de un producto sí tiene sentido [09:00]:
typescript this.productRepo.findOne(id, { relations: ['brand', 'categories'], });
Esto devuelve el producto con la marca y el array de categorías asociadas [09:50].
¿Cómo resolver la relación inversa en categorías?
La relación muchos a muchos es bidireccional. Si al consultar el detalle de una categoría quieres saber qué productos le pertenecen, basta con agregar la relación en el findOne del controlador de categorías [10:30]:
typescript this.categoryRepo.findOne(id, { relations: ['products'], });
El resultado muestra la categoría con su array de productos asociados, confirmando que una categoría puede tener muchos productos y un producto puede tener muchas categorías [11:00].
Algunos puntos clave para recordar:
- Usa
findByIdspara resolver múltiples entidades en una sola consulta. - Inyecta repositorios directamente cuando el servicio agrega abstracciones innecesarias.
- Controla qué relaciones se resuelven según el contexto: listado vs. detalle.
- Vigila el tamaño del response para evitar enviar datos que el consumidor no necesita.
Con las relaciones uno a uno, uno a muchos y muchos a muchos cubiertas, queda pendiente un tema fundamental: cómo modificar dinámicamente ese array de relaciones, por ejemplo, agregar o quitar categorías de un producto existente. ¿Cómo lo resolverías tú?