skip to Main Content

The following is my Prisma Schema for 3 models –> User, Cart and Item.

model User {
  id             String  @id @default(auto()) @map("_id") @db.ObjectId
  name           String
  email          String  @unique
  hashedPassword String
  isAdmin        Boolean @default(false)
  cart           Cart?
}

model Cart {
  id      String   @id @default(auto()) @map("_id") @db.ObjectId

  user    User     @relation(fields: [userId], references: [id])
  userId  String   @unique @db.ObjectId

  itemIDs String[] @db.ObjectId
  items   Item[]   @relation(fields: [itemIDs], references: [id])
}

model Item {
  id           String   @id @default(auto()) @map("_id") @db.ObjectId
  name         String
  category     String?
  description  String?
  color        String?
  price        Float
  listImageUrl String[]

  carts        Cart[]   @relation(fields: [cartIDs], references: [id])
  cartIDs      String[] @db.ObjectId
}

I want to define an explicit many – many relation for Cart and Item and also adding one more attribute, quantity Int to keep track the number of copies of Item in the Cart a User has.

I tried doing this:

model CartItem {
    cart   Cart   @relation(fields: [cartId], references: [id])
    cartId String

    item   Item   @relation(fields: [itemId], references: [id])
    itemId String

    quantity Int @default(1)
    
    // *** THIS IS MY PROBLEM ***
    @@id([cartId, itemId]) // But Compound Key's are not supported for MongoDB. 
}

What can we do here?

I referred the following Prisma docs but it only explains the syntax for implicit many-many relation.
https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#mongodb

2

Answers


  1. Edit: Relations in the embedded document are not yet supported in Prisma. Instead of the compound key in CartItem, you can use the @db.ObjectId for the id field.

    Instead of creating CartItem as a separate model, make this an embedded document. This will save CartItem as a sub-document in the Cart model. You can even create the Cart as a sub-document in the User model.

    model User {
      id             String  @id @default(auto()) @map("_id") @db.ObjectId
      name           String
      email          String  @unique
      hashedPassword String
      isAdmin        Boolean @default(false)
      cart           Cart?
    }
    
    model Cart {
      id      String   @id @default(auto()) @map("_id") @db.ObjectId
    
      user    User     @relation(fields: [userId], references: [id])
      userId  String   @unique @db.ObjectId
    
      items CartItem[]
    }
    
    model Item {
      id           String   @id @default(auto()) @map("_id") @db.ObjectId
      name         String
      category     String?
      description  String?
      color        String?
      price        Float
      listImageUrl String[]
    
      carts        Cart[]   @relation(fields: [cartIDs], references: [id])
      cartIDs      String[] @db.ObjectId
    }
    
    type CartItem {
        item   Item   @relation(fields: [itemId], references: [id])
        itemId String
    
        quantity Int @default(1) 
    }
    
    Login or Signup to reply.
  2. I need to solve the same problem, how did you do it?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search