zod-prisma-types
zod-prisma-types copied to clipboard
It's not possible to omit relation field
With this schema:
model Article {
id Int @id @default(autoincrement())
authorId Int?
author User? @relation(fields: [authorId], references: [id])
}
it generates
export const ArticleCreateInputSchema: z.ZodType<Prisma.ArticleCreateInput> = z
.object({
author: z.lazy(() => UserCreateNestedOneWithoutArticlesInputSchema).optional()
})
.strict();
export const ArticleUncheckedCreateInputSchema: z.ZodType<Omit<Prisma.ArticleUncheckedCreateInput, "userId">> = z
.object({
id: z.number().int().optional(),
authorId: z.number().int().optional().nullable()
})
.strict();
You can add omit
to authorId
model Article {
id Int @id @default(autoincrement())
authorId Int? /// @zod.custom.omit([input])
author User? @relation(fields: [authorId], references: [id])
}
to get this
export const ArticleCreateInputSchema: z.ZodType<Prisma.ArticleCreateInput> = z
.object({
author: z.lazy(() => UserCreateNestedOneWithoutArticlesInputSchema).optional()
})
.strict();
export const ArticleUncheckedCreateInputSchema: z.ZodType<Omit<Prisma.ArticleUncheckedCreateInput, "userId">> = z
.object({
id: z.number().int().optional(),
// omitted: authorId: z.number().int().optional().nullable() })
.strict();
It's still possible to create article with author using author: { connect: { id } }
instead of authorId
And if you try to add omit
to author
too
model Article {
id Int @id @default(autoincrement())
authorId Int? /// @zod.custom.omit([input])
author User? @relation(fields: [authorId], references: [id]) /// @zod.custom.omit([input])
}
you recieve an error:
[@zod generator error]: Validator 'custom' is not valid for type 'User'. [Error Location]: Model: 'Article', Field: 'author'.
@oceandrama thanks for the hint. I need to look into this in more detail but I think it is because the omitted fields are currently only propagated to the "normal" create
, update
, etc. input types and not to the nested ones.
I think it is because the omitted fields are currently only propagated to the "normal" create, update, etc. input types and not to the nested ones.
Glad I found this issue, was messing up my use case. Will leave some info incase it helps.
Relevant model from my schema:
model Task {
id String @id @default(auto()) @map("_id") @db.ObjectId
completed Boolean @default(false)
title String /// @zod.string.min(1)
size TaskSize @default(MEDIUM)
description String?
number Int /// @zod.custom.omit(["model", "input"])
start DateTime? // Date at which this task can be worked on
end DateTime? // Day this task is due
url String? // Page that triggered this task to be created
User User @relation(fields: [userEmail], references: [email])
userEmail String @unique
}
I am validating my input using the generated TaskUncheckedCreateWithoutUserInputSchema
, but was confused why the annotation on the number
field wasn't seeming to propogate to the generated schema. I generate that value serverside and append it to the user input, so wanted to omit it from the input types.
I suppose my solution will be to use the base unchecked input type, and simply omit both the user and number types from the input. Would be nice to get support added for the omits on the non-base input versions at some point in the future, or at least update the README to make that clearer.
EDIT: Yep, worked like a charm. As per the OP though, I think you have to stick to the unchecked schema variants for it to work properly.
Just thought I'd bump this as well, running into a simlar issue. My use case is that when a user applies for a job, we want to auto-fill the applicant from the auth context.
model JobApplication {
id String @id @default(cuid())
cover_letter String
job_post JobPost @relation(fields: [job_post_id], references: [id], onDelete: Cascade)
job_post_id String
applicant Profile @relation(fields: [applicant_id], references: [id], onDelete: Cascade)
applicant_id String /// @zod.custom.omit([input])
@@index([job_post_id])
@@index([applicant_id])
}
Using the unchcked inputs isn't too practical in my example
const application = await ctx.prisma.jobApplication.create({
data: {
...input,
job_post_id: undefined,
applicant: {
connect: {
id: ctx.session.user.profile_id,
},
},
job_post: {
connect: {
id: input.job_post_id,
},
},
},
});
Ideally would love to be able to go
...
applicant Profile @relation(fields: [applicant_id], references: [id], onDelete: Cascade) /// @zod.custom.omit([input])
...
const application = await ctx.prisma.jobApplication.create({
data: {
...input,
applicant: {
connect: {
id: ctx.session.user.profile_id,
},
},
},
});```