Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested relations not exposed in a polymorphic relation #1994

Open
simoami opened this issue Feb 20, 2025 · 1 comment
Open

Nested relations not exposed in a polymorphic relation #1994

simoami opened this issue Feb 20, 2025 · 1 comment

Comments

@simoami
Copy link

simoami commented Feb 20, 2025

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 },
                },
              },
            ],
          },
        },
      },
    },
  })
@ymc9
Copy link
Member

ymc9 commented Feb 24, 2025

Hi @simoami , thanks for filing this!

It seems to be pure typing issue. If you make a cast to "any", both attempt 1 and 2 should work at runtime. I'll see how to fix the typing problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants