Skip to content

Commit d345b80

Browse files
committed
fix(polymorphism): support orderBy with base fields
1 parent 6e7993a commit d345b80

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

packages/runtime/src/enhancements/delegate.ts

+22-12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
7777
this.injectWhereHierarchy(model, args?.where);
7878
this.injectSelectIncludeHierarchy(model, args);
7979

80+
if (args.orderBy) {
81+
// `orderBy` may contain fields from base types
82+
args.orderBy = this.buildWhereHierarchy(this.model, args.orderBy);
83+
}
84+
8085
if (this.options.logPrismaQuery) {
8186
this.logger.info(`[delegate] \`${method}\` ${this.getModelName(model)}: ${formatObject(args)}`);
8287
}
@@ -126,19 +131,19 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
126131
});
127132
}
128133

129-
private buildWhereHierarchy(where: any) {
134+
private buildWhereHierarchy(model: string, where: any) {
130135
if (!where) {
131136
return undefined;
132137
}
133138

134139
where = deepcopy(where);
135140
Object.entries(where).forEach(([field, value]) => {
136-
const fieldInfo = resolveField(this.options.modelMeta, this.model, field);
141+
const fieldInfo = resolveField(this.options.modelMeta, model, field);
137142
if (!fieldInfo?.inheritedFrom) {
138143
return;
139144
}
140145

141-
let base = this.getBaseModel(this.model);
146+
let base = this.getBaseModel(model);
142147
let target = where;
143148

144149
while (base) {
@@ -173,12 +178,17 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
173178

174179
for (const kind of ['select', 'include'] as const) {
175180
if (args[kind] && typeof args[kind] === 'object') {
176-
for (const [field, value] of Object.entries(args[kind])) {
177-
if (value !== undefined) {
181+
for (const [field, value] of Object.entries<any>(args[kind])) {
182+
const fieldInfo = resolveField(this.options.modelMeta, model, field);
183+
if (fieldInfo && value !== undefined) {
184+
if (value?.orderBy) {
185+
// `orderBy` may contain fields from base types
186+
value.orderBy = this.buildWhereHierarchy(fieldInfo.type, value.orderBy);
187+
}
188+
178189
if (this.injectBaseFieldSelect(model, field, value, args, kind)) {
179190
delete args[kind][field];
180191
} else {
181-
const fieldInfo = resolveField(this.options.modelMeta, model, field);
182192
if (fieldInfo && this.isDelegateOrDescendantOfDelegate(fieldInfo.type)) {
183193
let nextValue = value;
184194
if (nextValue === true) {
@@ -847,15 +857,15 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
847857
args = deepcopy(args);
848858

849859
if (args.cursor) {
850-
args.cursor = this.buildWhereHierarchy(args.cursor);
860+
args.cursor = this.buildWhereHierarchy(this.model, args.cursor);
851861
}
852862

853863
if (args.orderBy) {
854-
args.orderBy = this.buildWhereHierarchy(args.orderBy);
864+
args.orderBy = this.buildWhereHierarchy(this.model, args.orderBy);
855865
}
856866

857867
if (args.where) {
858-
args.where = this.buildWhereHierarchy(args.where);
868+
args.where = this.buildWhereHierarchy(this.model, args.where);
859869
}
860870

861871
if (this.options.logPrismaQuery) {
@@ -875,11 +885,11 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
875885
args = deepcopy(args);
876886

877887
if (args?.cursor) {
878-
args.cursor = this.buildWhereHierarchy(args.cursor);
888+
args.cursor = this.buildWhereHierarchy(this.model, args.cursor);
879889
}
880890

881891
if (args?.where) {
882-
args.where = this.buildWhereHierarchy(args.where);
892+
args.where = this.buildWhereHierarchy(this.model, args.where);
883893
}
884894

885895
if (this.options.logPrismaQuery) {
@@ -915,7 +925,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
915925
args = deepcopy(args);
916926

917927
if (args.where) {
918-
args.where = this.buildWhereHierarchy(args.where);
928+
args.where = this.buildWhereHierarchy(this.model, args.where);
919929
}
920930

921931
if (this.options.logPrismaQuery) {

tests/integration/tests/enhancements/with-delegate/enhanced-client.test.ts

+35
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,41 @@ describe('Polymorphism Test', () => {
235235
expect(imgAsset.owner).toMatchObject(user);
236236
});
237237

238+
it('order by base fields', async () => {
239+
const { db, user } = await setup();
240+
241+
await expect(
242+
db.video.findMany({
243+
orderBy: { viewCount: 'desc' },
244+
})
245+
).resolves.toHaveLength(1);
246+
247+
await expect(
248+
db.ratedVideo.findMany({
249+
orderBy: { duration: 'asc' },
250+
})
251+
).resolves.toHaveLength(1);
252+
253+
await expect(
254+
db.user.findMany({
255+
orderBy: { assets: { _count: 'desc' } },
256+
})
257+
).resolves.toHaveLength(1);
258+
259+
await expect(
260+
db.user.findUnique({
261+
where: { id: user.id },
262+
include: {
263+
ratedVideos: {
264+
orderBy: {
265+
viewCount: 'desc',
266+
},
267+
},
268+
},
269+
})
270+
).toResolveTruthy();
271+
});
272+
238273
it('update simple', async () => {
239274
const { db, videoWithOwner: video } = await setup();
240275

0 commit comments

Comments
 (0)