Skip to content

Commit b3cb083

Browse files
authored
Correción data loaders: Orden de IDs para asociar correctamente los objetos en GraphQL (#258)
Este Pull Request corrige un bug relacionado con el orden de los objetos devueltos, lo que estaba causando asociaciones incorrectas de datos. Los cambios principales incluyen: - Rediseño de data loaders: Se han modificado los data loaders en los esquemas de PurchaseOrder, Schedule, Session, Speaker, Ticket y User para garantizar que los resultados se devuelvan en el mismo orden que los IDs solicitados. - Preservación del orden de IDs: Se ha implementado un sistema basado en Map dentro de los data loaders para indexar los resultados por ID, permitiendo una recuperación ordenada y rápida. - Manejo de elementos no encontrados: Los data loaders ahora manejan casos donde ciertos IDs solicitados no existen, devolviendo errores específicos para cada tipo de objeto (lo cual permite mantener el orden de los IDs y devolver null por ejemplo)
1 parent 19047b7 commit b3cb083

7 files changed

Lines changed: 85 additions & 32 deletions

File tree

src/schema/events/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,19 @@ const EventsTicketTemplateSearchInput = builder.inputType(
8787
export const EventLoadable = builder.loadableObject(EventRef, {
8888
description:
8989
"Representation of an Event (Events and Users, is what tickets are linked to)",
90-
load: (ids: string[], context) =>
91-
eventsFetcher.searchEvents({
90+
load: async (ids: string[], context) => {
91+
const result = await eventsFetcher.searchEvents({
9292
DB: context.DB,
9393
search: { eventIds: ids },
9494
sort: null,
95-
}),
95+
});
96+
97+
const resultByIdMap = new Map(result.map((item) => [item.id, item]));
98+
99+
return ids.map(
100+
(id) => resultByIdMap.get(id) || new Error(`Event ${id} not found`),
101+
);
102+
},
96103
fields: (t) => ({
97104
id: t.exposeID("id", { nullable: false }),
98105
name: t.exposeString("name", { nullable: false }),

src/schema/purchaseOrder/types.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,36 @@ export const PurchaseOrderRef = builder.objectRef<{
2727
export const PurchaseOrderLoadable = builder.loadableObject(PurchaseOrderRef, {
2828
description: "Representation of a Purchase Order",
2929
load: async (ids: string[], context) => {
30-
const purchaseOrders = await context.DB.query.purchaseOrdersSchema.findMany(
31-
{
30+
const result = await context.DB.query.purchaseOrdersSchema
31+
.findMany({
3232
where: (t, { inArray }) => inArray(t.id, ids),
3333
with: {
34-
userTickets: true,
34+
userTickets: {
35+
columns: {
36+
id: true,
37+
},
38+
},
3539
},
36-
},
37-
);
40+
})
41+
.then((purchaseOrders) => {
42+
return purchaseOrders.map((somePurchaseOrder) => {
43+
const ticketsIds = somePurchaseOrder.userTickets.map((ut) => ut.id);
44+
45+
return {
46+
ticketsIds,
47+
purchaseOrder: selectPurchaseOrdersSchema.parse(somePurchaseOrder),
48+
};
49+
});
50+
});
3851

39-
return purchaseOrders.map((po) => {
40-
const parsedPurchaseOrder = selectPurchaseOrdersSchema.parse(po);
41-
const ticketsIds = po.userTickets.map((ut) => ut.id);
52+
const resultByIdMap = new Map(
53+
result.map((item) => [item.purchaseOrder.id, item]),
54+
);
4255

43-
return {
44-
ticketsIds,
45-
purchaseOrder: parsedPurchaseOrder,
46-
};
47-
});
56+
return ids.map(
57+
(id) =>
58+
resultByIdMap.get(id) || new Error(`Purchase Order ${id} not found`),
59+
);
4860
},
4961
fields: (t) => ({
5062
id: t.field({

src/schema/schedules/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,18 @@ export const ScheduleRef = builder.objectRef<ScheduleraphqlSchema>("Schedule");
1919

2020
export const ScheduleLoadable = builder.loadableObject(ScheduleRef, {
2121
description: "Representation of a Schedule",
22-
load: (ids: string[], context) =>
23-
schedulesFetcher.searchSchedules({
22+
load: async (ids: string[], context) => {
23+
const result = await schedulesFetcher.searchSchedules({
2424
DB: context.DB,
2525
search: { scheduleIds: ids },
26-
}),
26+
});
27+
28+
const resultByIdMap = new Map(result.map((item) => [item.id, item]));
29+
30+
return ids.map(
31+
(id) => resultByIdMap.get(id) || new Error(`Schedule ${id} not found`),
32+
);
33+
},
2734
fields: (t) => ({
2835
id: t.exposeID("id", { nullable: false }),
2936
title: t.exposeString("title", { nullable: false }),

src/schema/sessions/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@ export const SessionRef = builder.objectRef<SessionGraphqlSchema>("Session");
1515

1616
export const SessionLoadable = builder.loadableObject(SessionRef, {
1717
description: "Representation of a Session",
18-
load: (ids: string[], context) =>
19-
sessionsFetcher.searchSessions({
18+
load: async (ids: string[], context) => {
19+
const result = await sessionsFetcher.searchSessions({
2020
DB: context.DB,
2121
search: { sessionIds: ids },
22-
}),
22+
});
23+
24+
const resultByIdMap = new Map(result.map((item) => [item.id, item]));
25+
26+
return ids.map(
27+
(id) => resultByIdMap.get(id) || new Error(`Session ${id} not found`),
28+
);
29+
},
2330
fields: (t) => ({
2431
id: t.exposeID("id", { nullable: false }),
2532
title: t.exposeString("title", { nullable: false }),

src/schema/speakers/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,19 @@ export const SpeakerRef = builder.objectRef<SpeakerGraphqlSchema>("Speaker");
1313

1414
export const SpeakerLoadable = builder.loadableObject(SpeakerRef, {
1515
description: "Representation of a Speaker",
16-
load: (ids: string[], context) =>
17-
speakersFetcher.searchSpeakers({
16+
load: async (ids: string[], context) => {
17+
const result = await speakersFetcher.searchSpeakers({
1818
DB: context.DB,
1919
search: { speakerIds: ids },
2020
sort: null,
21-
}),
21+
});
22+
23+
const resultByIdMap = new Map(result.map((item) => [item.id, item]));
24+
25+
return ids.map(
26+
(id) => resultByIdMap.get(id) || new Error(`Speaker ${id} not found`),
27+
);
28+
},
2229
fields: (t) => ({
2330
id: t.exposeID("id", { nullable: false }),
2431
name: t.exposeString("name", { nullable: false }),

src/schema/ticket/types.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,17 @@ builder.objectType(PriceRef, {
3434

3535
export const TicketLoadable = builder.loadableObject(TicketRef, {
3636
description: "Representation of a ticket",
37-
load: (ids: string[], context) =>
38-
context.DB.query.ticketsSchema.findMany({
37+
load: async (ids: string[], context) => {
38+
const result = await context.DB.query.ticketsSchema.findMany({
3939
where: (t, { inArray }) => inArray(t.id, ids),
40-
}),
40+
});
41+
42+
const ticketMap = new Map(result.map((ticket) => [ticket.id, ticket]));
43+
44+
return ids.map(
45+
(id) => ticketMap.get(id) || new Error(`Ticket ${id} not found`),
46+
);
47+
},
4148
fields: (t) => ({
4249
id: t.exposeID("id"),
4350
name: t.exposeString("name"),

src/schema/user/types.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,20 @@ const RSVPFilterInput = builder.inputType("RSVPFilterInput", {
3232

3333
export const UserLoadable = builder.loadableObject(UserRef, {
3434
description: "Representation of a user",
35-
load: async (ids: string[], ctx) => {
36-
const users = await usersFetcher.searchUsers({
37-
DB: ctx.DB,
35+
load: async (ids: string[], { DB }) => {
36+
const result = await usersFetcher.searchUsers({
37+
DB,
3838
search: { userIds: ids },
3939
sort: null,
4040
});
4141

42-
return users.map((user) => selectUsersSchema.parse(user));
42+
const resultByIdMap = new Map(
43+
result.map((item) => [item.id, selectUsersSchema.parse(item)]),
44+
);
45+
46+
return ids.map(
47+
(id) => resultByIdMap.get(id) || new Error(`Speaker ${id} not found`),
48+
);
4349
},
4450
fields: (t) => ({
4551
id: t.exposeID("id", { nullable: false }),

0 commit comments

Comments
 (0)