Prisma Datamodel:主键作为两个关系模型的组合

dev*_*tor 5 mysql graphql prisma

我在 Prisma 数据建模中遇到了一个问题,我必须限制用户只能提交一个产品评论。我对非约束情况以下设计

应该CustomerProduct组合成ProductReview模型中的主键,还是应该在应用程序服务器级别而不是在数据库级别强加这种约束?

现在的数据模型(非约束版本):

type Product {
  id: ID! @unique
  title: String!
  reviews: [ProductReview!]! @relation(name: "ProductReviews", onDelete: CASCADE)
}

type Customer {
  id: ID! @unique
  email: String @unique
}

type ProductReview {
  id: ID! @unique
  forProduct: Product! @relation(name: "ProductReviews", onDelete: SET_NULL)
  byCustomer: Customer!
  review: String!
  ratinng: Float!
}
Run Code Online (Sandbox Code Playgroud)

Cym*_*men 18

Prisma v2 引入了复合主键:

https://newreleases.io/project/github/prisma/prisma/release/2.0.0-preview023

该链接的一个示例:

model User {
  firstName String
  lastName  String
  email     String

  @@id([firstName, lastName])
}
Run Code Online (Sandbox Code Playgroud)

因此,在给定的问题示例中,现在可以添加ProductReview

@@id([id, forProduct])
Run Code Online (Sandbox Code Playgroud)


nbu*_*urk 2

我必须限制用户只能对产品提交一篇评论。对于非约束情况,我有以下设计。

不幸的是,目前 Prisma 无法实现这一点。已经有一个开放的功能请求要求此功能,请留下您的问题!

要在应用程序中获得该功能,您需要在应用程序层(例如express、apollo-server 或graphql-yoga)上手动实现该约束。

您可以查看How to GraphQL 的页面,其中User,LinkVote类型也有类似的情况。以下是如何使用 graphql-yoga 实现解析器创建Vote并确保该用户不投票:

async function vote(parent, args, context, info) {
  // 1
  const userId = getUserId(context)

  // 2
  const linkExists = await context.db.exists.Vote({
    user: { id: userId },
    link: { id: args.linkId },
  })
  if (linkExists) {
    throw new Error(`Already voted for link: ${args.linkId}`)
  }

  // 3
  return context.db.mutation.createVote(
    {
      data: {
        user: { connect: { id: userId } },
        link: { connect: { id: args.linkId } },
      },
    },
    info,
  )
}
Run Code Online (Sandbox Code Playgroud)