Closed
Description
Description and expected behavior
Suppose you have an m-to-n relation: OrganizationRole
<- OrganizationRolePrivilege
-> Privilege
. The Organization role is a delegate further breaking down into 2 concrete models: SystemDefinedRole
and CustomOrganizationRole
:
model OrganizationRole {
id Int @id @default(autoincrement())
name String
rolePrivileges OrganizationRolePrivilege[]
type String
@@delegate(type)
}
// roles common to all orgs, defined once
model SystemDefinedRole extends OrganizationRole {
name String @unique
}
// roles specifc to each org
model CustomOrganizationRole extends OrganizationRole {
name String
organizationId Int
organization Organization @relation(fields: [organizationId], references: [id])
@@unique([organizationId, name])
@@index([organizationId])
}
model OrganizationRolePrivilege {
organizationRoleId Int
privilegeId Int
organizationRole OrganizationRole @relation(fields: [organizationRoleId], references: [id])
privilege Privilege @relation(fields: [privilegeId], references: [id])
@@id([organizationRoleId, privilegeId])
}
model Privilege {
id Int @id @default(autoincrement())
name String // e.g. "org:manage"
orgRolePrivileges OrganizationRolePrivilege[]
@@unique([name])
}
With the Privilege
table is already preloaded with all privileges, it's not possible to create a new concrete Role and connect it to existing privileges.
Below are a few attempts but unsuccessful:
Attempt 1: Connecting by foreign key
await db.systemDefinedRole.create({
data: {
name: 'Admin',
rolePrivileges: {
create: [
{
privilegeId: 1,
// ✖ currently requires a organizationRoleId but organizationRole not created yet
organizationRoleId:1
}
],
},
},
});
Attempt 2: Connecting by a relation name
await db.systemDefinedRole.create({
data: {
name: 'Admin',
rolePrivileges: {
create: [
{
// ✖ privilege relation not exposed
privilege: {
connect: { id: 1 },
},
},
],
},
},
})
Environment (please complete the following information):
- ZenStack version: 2.11.6
- Prisma version: 5.22.0
- Database type: Postgresql
Additional context
See related Discord thread.
With raw Prisma, this is achievable in 2 different ways. Both of which expose the privilege
relation to connect to:
const db = await prismaEnhanced({ bypassPolicy: true})
const privileges = await db.privilege.createMany({
data: [...orgPrivileges, ...studyPrivileges],
})
// 1. Using raw prisma with the OrganizationRole delegate model
await prisma.organizationRole.create({
data: {
// name: 'Owner',
description:
'Admin access',
type: 'SystemDefinedRole',
delegate_aux_systemDefinedRole: {
create: { name: 'Admin' },
},
rolePrivileges: {
create: [
{
privilege: {
connect: { id: 1 },
},
},
],
},
},
})
// 2: Using raw prisma with the SystemDefinedRole concrete model
await prisma.systemDefinedRole.create({
data: {
name: 'Admin',
delegate_aux_organizationRole: {
create: {
description:
'Admin access',
type: 'SystemDefinedRole',
rolePrivileges: {
create: [
{
privilege: {
connect: { id: 1 },
},
},
],
},
},
},
},
})