繁体   English   中英

得到一个嵌套的 email 字段,它是棱镜中另一个 model 的一部分?

[英]get a nested email field that is part of another model in prisma?

我的架构看起来像:

模式棱镜

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model User {
  id       String  @id @default(cuid())
  email    String? @unique
  stripeId String  @unique

  createdAt DateTime @default(now())

  product Product?

  @@map("users")
}

model Product {
  id       String @id @default(cuid())
  totalSum Int    @default(9700)

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

  licenses License[]

  @@map("products")
}

model License {
  id    String @id @default(cuid())
  name  String @unique
  /// no. of licenses generated
  total Int    @default(1)
  /// no. of licenses used
  used  Int    @default(0)
  /// stored in cents

  product   Product? @relation(fields: [productId], references: [id])
  productId String?

  createdAt DateTime @default(now())

  @@map("licenses")
}

我想在执行prisma.license.findMany()时访问email字段。 我的db文件看起来像:

数据库.ts

import { Prisma, License, User } from '@prisma/client'

import { prisma } from './context'

export const getLicenses = async (): Promise<
  Array<License & Pick<User, 'email'>> | null | undefined
> => {
  const userSelect = Prisma.validator<Prisma.ProductSelect>()({
    user: {
      select: {
        email: true,
      },
    },
  })

  const productSelect = Prisma.validator<Prisma.LicenseSelect>()({
    product: {
      include: userSelect,
    },
  })

  const licenses = await prisma.license.findMany({
    orderBy: {
      createdAt: 'desc',
    },
    include: productSelect,
  })

  const result = licenses.map((license) => {
    const email = license.product?.user.email

    if (email) {
      return {
        ...license,
        email,
      }
    }
  })

  return result
}

export const db = {
  getLicenses,
}

最后一行return result给出了这个 typescript 错误:

Type '({ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined)[]' is not assignable to type '(License & Pick<User, "email">)[]'.
  Type '{ email: string; id: string; name: string; total: number; used: number; productId: string | null; createdAt: Date; product: (Product & { user: { email: string | null; }; }) | null; } | undefined' is not assignable to type 'License & Pick<User, "email">'.
    Type 'undefined' is not assignable to type 'License & Pick<User, "email">'.
      Type 'undefined' is not assignable to type 'License'.ts(2322)

我的架构文件如下所示:

架构.ts

import { db } from './db'

const Query = objectType({
  name: 'Query',
  definition(t) {
    t.list.field('licenses', {
      type: 'License',
      resolve: async (_, __, ctx) => {
        if (!ctx.admin.isLoggedIn) return null
        const licenses = await db.getLicenses()

        if (licenses) return licenses
        return null
      },
    })
  },
})

即使是这个小查询也给我带来了很多错误。 当我想使用prisma.license.findMany()查询所有许可证时,它曾经可以工作,但是一旦我想要email字段但采用平面文件格式,它就开始抛出错误,所以我的 output 看起来像:

{
    id: string;
    name: string;
    total: number;
    used: number;
    productId: string | null;
    createdAt: Date;
    email: string;
}

我也不希望发送productId 我该如何解决这个问题?

我做了一个最小的复制→ https://github.com/deadcoder0904/prisma-nested-query-email

当您使用 Array.map 时,如果您没有明确指定每个元素的返回值,那么undefined将进入您的数组 - 这就是您的 TS 错误所指示的内容。 如果 (,email),则 map 将undefined的元素返回到 output 数组。

本质上,您想要过滤那些与 email 和 THEN map 关联的用户的许可证。

你实际上可以用 reduce 来做到这一点。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#replace_.filter.map_with_.reduce

您正在尝试使用 Array.map LIKE 这个 Array.reduce 功能(可以替换过滤器/映射)。 但是如果你用 Array.reduce 实现 undefined 就不能潜入返回的数组。

这是一个相关的 CodeSandbox 链接。 请注意, eslint 正在抱怨(预计在箭头函数的末尾返回一个值)。 https://codesandbox.io/s/nifty-surf-s8vcg6?file=/src/index.ts

我在db.ts文件上禁用了 TS,然后检查了results数组并发现我需要将emailnull而不是undefined

一个重要的注意事项:我必须停止在License类型的nexus配置中对email使用nonNull来停止错误。

工作解决方案发布在此提交中。 现在可以了:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM