Hey all. Looking for some help here. I am trying t...
# orm-help
s
Hey all. Looking for some help here. I am trying to implement a polymorphic relation in prisma with postgresql. I have the following models • User : a user • App : an App • Dateset: a Datasets • Collaborator: A user with permissions to edit, view etc either an App or a Dataset I have tried to set this up two different ways. First, the simpler looks like
Copy code
enum ResourceType {
  App
  Dataset
}

model App {
  id            String         @id @default(cuid())
  spec          Json
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @default(now())
  name          String
  description   String
  public        Boolean
  ownerId       String
  noViews       Int            @default(0)
  noForks       Int            @default(0)
  owner         User           @relation(fields: [ownerId], references: [id])
  collaborators Collaborator[] @relation("AppColaborator")

  @@map("apps")
}

model Dataset {
  id            String         @id @default(cuid())
  createdAt     DateTime       @default(now())
  name          String
  description   String
  public        Boolean
  path          String
  ownerId       String
  owner         User           @relation(fields: [ownerId], references: [id])
  collaborators Collaborator[] @relation("DatasetColaborator")

  @@map("datasets")
}


model User {
  id             String         @id @default(cuid())
  name           String?
  apps           App[]
  collaborations Collaborator[]
  Datasets       Dataset[]
  @@map("users")
}


model Collaborator {
  id           String       @id @default(cuid())
  user         User         @relation(fields: [userId], references: [id])
  userId       String
  appId        String?
  datasetId    String?
  resourceType ResourceType
  view         Boolean
  edit         Boolean
  manage       Boolean
  app          App?         @relation("AppColaborator", fields: [appId], references: [id], map: "app_colaboration_id")
  dataset      Dataset?     @relation("DatasetColaborator", fields: [datasetId], references: [id], map: "dataset_colaboration_id")

  @@unique([userId, appId, datasetId])
  @@map("collaborators")
}
The issue with this is if I try and create or upsert a Collaborator object, I cant because one of the appId or datasetId needs to be undefined which prisma rejects. The other approach I have tried is to have a single resourceId with a resourceType that defines what kind of resource this is and define two relationships like so
Copy code
model Collaborator {
  id           String       @id @default(cuid())
  user         User         @relation(fields: [userId], references: [id])
  userId       String
  resourceId   String
  resourceType ResourceType
  view         Boolean
  edit         Boolean
  manage       Boolean
  app          App?         @relation("AppColaborator", fields: [resourceId], references: [id], map: "app_colaboration_id")
  dataset      Dataset?     @relation("DatasetColaborator", fields: [resourceId], references: [id], map: "dataset_colaboration_id")
  @@unique([userId, resourceId])
  @@map("collaborators")
}
However that fails when I try to create a new collaborator because both foreign key constraints for datasetId and appId cant both be satisfied. Is there a good model or example for doing this kind of thing? A little stumped here
1
Seems this would be a common pattern for permission tables / likes etc but cant find a good example on how to solve it?
Ok so reading in to this further it seems like it might not be possible. Going use the first approach and drop the unique requirement and just check that in code. Would be really great to have some guidance on this. Otherwise loving using prisma!
r
Hi @stuart Lynn 👋 At the moment Prisma doesn't have support for Polymorphic association. However there is a feature request in that regard. You might want to add your usecase there.
s
Will do thanks!
r
You're welcome