prisma数据模型:作为两个关系模型组合的主键

kg7wmglp  于 2021-06-19  发布在  Mysql
关注(0)|答案(3)|浏览(655)

我在prisma数据建模中遇到了一个问题,我必须限制一个用户只能为一个产品提交一个评论。我有以下非约束情况的设计。
应该 Customer 以及 Product 组合成主键 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!
}
qyswt5oh

qyswt5oh1#

我将从mysql的Angular 来回答。如果您想强制一个给定的客户只能与一个给定的产品关联一次,那么您应该 (cusotmer_id, product_id) 中的唯一键(可能是主键) ProductReview 表格:

ALTER TABLE ProductReview ADD UNIQUE KEY uk_cust_prod (customer_id, product_id);

这意味着,当这种关系已经存在时,任何为给定客户和产品插入记录的尝试都将在数据库级别失败。
如果您还想为此添加一个应用程序级检查,那么您当然可以这样做,也许可以先在那里处理它。

s4n0splo

s4n0splo2#

有一个解决办法。实现像sql这样的多个主键的概念。想法很简单,在“productreview”下再创建一个名为“uniquecustomerreview”的字段。在进行变异时,将“uniquecustomerreview”值设置为“[customeremail][productid]”。所以我们现在可以使用prisma的默认unique。
您的数据模型如下所示:

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!
  UniqueCustomerReview:String!  # adding a extra field
}

创建或删除查询:

mutation{
createProductReview(
data:{
forProduct: {"connect":{"id":"<Replacec_with_product_id>"}}
byCustomer: {"connect":{"email":"<Replacec_with_customer_email>"}}
review: "my product review..."
ratinng: 5.0
UniqueCustomerReview:"loggedInUser@email.com_<Poductid>" # replace the string with user email and product id. this will create a unique product review for the user alone.
      }
                   )
{
UniqueCustomerReview

# ... any requied fields

}
        }
7gcisfzg

7gcisfzg3#

我必须限制一个用户只能为一个产品提交一个评论。我有以下非约束情况的设计。
不幸的是,prisma目前无法做到这一点。已经有一个打开的功能请求要求此功能,请留下您的?在这个问题上!
要在应用程序中获得该功能,您需要在应用程序层(例如express、apollo server或graphql)上手动实现该约束。
您可以看看这个页面,了解如何在与 User , Link 以及 Vote 类型。下面是解析器如何创建 Vote 并确保不存在来自该用户的投票,并使用graphql实现:

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,
  )
}

相关问题