Skip to content

Commit 4d9d093

Browse files
authored
fix: make sure fields inherited from abstract base models are properly recognized as id (#1130)
1 parent be9be0c commit 4d9d093

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

packages/sdk/src/utils.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,14 @@ export function isIdField(field: DataModelField) {
218218
return true;
219219
}
220220

221+
// NOTE: we have to use name to match fields because the fields
222+
// may be inherited from an abstract base and have cloned identities
223+
221224
const model = field.$container as DataModel;
222225

223226
// model-level @@id attribute with a list of fields
224227
const modelLevelIds = getModelIdFields(model);
225-
if (modelLevelIds.includes(field)) {
228+
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
226229
return true;
227230
}
228231

@@ -234,12 +237,12 @@ export function isIdField(field: DataModelField) {
234237
// then, the first field with @unique can be used as id
235238
const firstUniqueField = model.fields.find((f) => hasAttribute(f, '@unique'));
236239
if (firstUniqueField) {
237-
return firstUniqueField === field;
240+
return firstUniqueField.name === field.name;
238241
}
239242

240243
// last, the first model level @@unique can be used as id
241244
const modelLevelUnique = getModelUniqueFields(model);
242-
if (modelLevelUnique.includes(field)) {
245+
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
243246
return true;
244247
}
245248

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { createPostgresDb, dropPostgresDb, loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('Regression for issue 1129', () => {
4+
it('regression', async () => {
5+
let prisma;
6+
const dbUrl = await createPostgresDb('regression-issue-1129');
7+
8+
try {
9+
const r = await loadSchema(
10+
`
11+
model Relation1 {
12+
id String @id @default(cuid())
13+
field1 String
14+
concrete Concrete[]
15+
@@allow('all', true)
16+
}
17+
18+
model Relation2 {
19+
id String @id @default(cuid())
20+
field2 String
21+
concrete Concrete[]
22+
@@allow('all', true)
23+
}
24+
25+
abstract model WithRelation1 {
26+
relation1Id String
27+
relation1 Relation1 @relation(fields: [relation1Id], references: [id])
28+
}
29+
abstract model WithRelation2 {
30+
relation2Id String
31+
relation2 Relation2 @relation(fields: [relation2Id], references: [id])
32+
}
33+
34+
model Concrete extends WithRelation1, WithRelation2 {
35+
concreteField String
36+
@@id([relation1Id, relation2Id])
37+
@@allow('all', true)
38+
}
39+
`,
40+
{ provider: 'postgresql', dbUrl }
41+
);
42+
43+
prisma = r.prisma;
44+
const db = r.enhance();
45+
46+
await db.$transaction(async (tx: any) => {
47+
await tx.relation2.createMany({
48+
data: [
49+
{
50+
id: 'relation2Id1',
51+
field2: 'field2Value1',
52+
},
53+
{
54+
id: 'relation2Id2',
55+
field2: 'field2Value2',
56+
},
57+
],
58+
});
59+
60+
await tx.relation1.create({
61+
data: {
62+
field1: 'field1Value',
63+
concrete: {
64+
createMany: {
65+
data: [
66+
{
67+
concreteField: 'concreteFieldValue1',
68+
relation2Id: 'relation2Id1',
69+
},
70+
{
71+
concreteField: 'concreteFieldValue2',
72+
relation2Id: 'relation2Id2',
73+
},
74+
],
75+
},
76+
},
77+
},
78+
});
79+
});
80+
} finally {
81+
if (prisma) {
82+
await prisma.$disconnect();
83+
}
84+
await dropPostgresDb('regression-issue-1129');
85+
}
86+
});
87+
});

0 commit comments

Comments
 (0)