Skip to content

Nested relations not exposed in a polymorphic relation #1994

Closed
@simoami

Description

@simoami

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 },
                },
              },
            ],
          },
        },
      },
    },
  })

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions