[英]get a nested email field that is part of another model in prisma?
i have schema that looks like:我的架构看起来像:
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")
}
i want to access email
field while doing prisma.license.findMany()
.我想在执行prisma.license.findMany()
时访问email
字段。 my db
file looks like:我的db
文件看起来像:
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,
}
the last line return result
gives this typescript error:最后一行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)
my schema file looks like:我的架构文件如下所示:
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
},
})
},
})
even this little query is causing me a lot of errors.即使是这个小查询也给我带来了很多错误。 it used to work when i wanted to query all of licenses using prisma.license.findMany()
but it started throwing errors as soon as i wanted email
field but in a flat file format so my output looks like:当我想使用prisma.license.findMany()
查询所有许可证时,它曾经可以工作,但是一旦我想要email
字段但采用平面文件格式,它就开始抛出错误,所以我的 output 看起来像:
{
id: string;
name: string;
total: number;
used: number;
productId: string | null;
createdAt: Date;
email: string;
}
i also don't want productId
to be sent.我也不希望发送productId
。 how can i solve this?我该如何解决这个问题?
i've made a minimal repro → https://github.com/deadcoder0904/prisma-nested-query-email我做了一个最小的复制→ https://github.com/deadcoder0904/prisma-nested-query-email
When you use Array.map, if you don't explicitly specify the return for every element, then undefined
will make its way into your array - which is what your TS error is indicating.当您使用 Array.map 时,如果您没有明确指定每个元素的返回值,那么undefined
将进入您的数组 - 这就是您的 TS 错误所指示的内容。 If (,email), then map returns an undefined
element to the output array.如果 (,email),则 map 将undefined
的元素返回到 output 数组。
Essentially, what you want is to filter those licenses that have an associated user with an email, and THEN map it.本质上,您想要过滤那些与 email 和 THEN map 关联的用户的许可证。
You can actually do this with reduce instead.你实际上可以用 reduce 来做到这一点。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#replace_.filter.map_with_.reduce https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#replace_.filter.map_with_.reduce
You're trying to use Array.map LIKE this Array.reduce functionality (which can replace filter/map).您正在尝试使用 Array.map LIKE 这个 Array.reduce 功能(可以替换过滤器/映射)。 But undefined can't sneak into the returned array if you implement with Array.reduce.但是如果你用 Array.reduce 实现 undefined 就不能潜入返回的数组。
Here's a relevant CodeSandbox link.这是一个相关的 CodeSandbox 链接。 Note that eslint is complaining (expected to return a value at the end of arrow function).请注意, eslint 正在抱怨(预计在箭头函数的末尾返回一个值)。 https://codesandbox.io/s/nifty-surf-s8vcg6?file=/src/index.ts https://codesandbox.io/s/nifty-surf-s8vcg6?file=/src/index.ts
I disabled TS on the db.ts
file & then checked results
array & figured out I needed to have email
as null
instead of undefined
.我在db.ts
文件上禁用了 TS,然后检查了results
数组并发现我需要将email
为null
而不是undefined
。
One important note: I had to stop using nonNull
for email
in nexus
configuration of type License
to stop the error.一个重要的注意事项:我必须停止在License
类型的nexus
配置中对email
使用nonNull
来停止错误。
The working solution is posted in this commit .工作解决方案发布在此提交中。 It works now:)现在可以了:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.