Hi, I’m having hard time to adapt the concept of ...
# orm-help
o
Hi, I’m having hard time to adapt the concept of supertype-subtype in Prisma schema. For example how do I implement this in Prisma schema terms? If I would do it like the typical 1-n prisma example:
Copy code
model Product {
  id        Int      @id @default(autoincrement())
  cars     Car[]
  boats    Boat[]
  planes.  Plane[]
}

model Car {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int
}

model Boat {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int
}

model Plane {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int
}
But it doesn’t feel intuitive to me. Is this the correct way in this case?
r
can the product be of multiple cars? wouldn't it be 1-1? the Product is a car?
I'm not sure if it's the "best" way, but if you kept down this current path, you could:
Copy code
model Product {
  id        Int      @id @default(autoincrement())
  carId     Int
  car       Car
  boatId    Int
  boat      Boat
  planeId   Int
  plane     Plane
}
and then in your model you could have:
Copy code
const Product = objectType({
  name: 'Product',
  definition(t) {
    t.model.id()
    t.model.car()
    t.model.carId()
    t.model.boat()
    t.model.boatId()
    t.model.plane()
    t.model.planeId()
    t.field.productType({
      resolve: (parent, args, context, info) => {
        if (parent.carId) {
          return PRODUCT_ENUM_CAR
        }
        // etc
      },
    })
    t.field.getProductType({/*more here*/})
  },
})
o
The problem with this approach is that is not going to scale well. The Car,Plane, Boat is just a simplified example. In reality I Could have many subtypes (20-30)
m
Not sure if there’s a better way, but just commenting on what you have ^ if it’s 1:1, why is it not like this:
Copy code
model Product {
  id        Int      @id @default(autoincrement())
  car     Car?
  boat    Boat?
  plane  Plane?
}
model Car {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int  @unique
}
model Boat {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int  @unique
}
model Plane {
  id        Int   @id @default(autoincrement())
  product   Product  @relation(fields: [productId], references: [id])
  productId  Int  @unique
}
If I was doing this in Nexus, I’d probably also add a
productType
enum field to the
model Product
, and make an object type like this:
Copy code
const product = objectType({
  name: 'Product',
  definition(t) {
    t.int('id')
    t.field('productType', { type: 'ProductTypeEnum' })
    t.field('details', {
      type: 'DetailsUnionType',
      resolve(root, _args, { prisma }) {
        if (root.productType === 'CAR') {
          return prisma.product.findUnique({ where: { id: root.id }}).car()
        } else ...
      }
    })
  }
})
🤷
r
even:
Copy code
resolve(root, _args, { prisma }) {
 return prisma[productType].findUnique({ where: { id: root.id }}).{productType}()
}
m
haha yeah. or
prisma[root.productType].findUnique({ where: { productId: root.id } })