model Product{
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
subcategoryId String @db.ObjectId
subcategory Subcategory? @relation(fields: [subcategoryId],references: [id])
categoryId String @db.ObjectId
category Category @relation(fields: [categoryId],references: [id])
price Float
brand String
isFeatured Boolean @default(false)
isArchived Boolean @default(false)
sizeId String[] @db.ObjectId
size Size[] @relation(fields: [sizeId], references: [id])
reviews Review[]
images ProductImage[]
orderItem OrderItem[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([categoryId])
@@index([sizeId])
}
model Subcategory{
id String @id @default(auto()) @map("_id") @db.ObjectId
billboardId String @db.ObjectId
billboard BillBoard @relation(fields: [billboardId],references: [id])
categoryId String @db.ObjectId
category Category @relation(fields: [categoryId],references: [id])
product Product[]
name String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
export const ProductSchema = z.object({
name: z.string().min(1),
categoryId: z.string().min(1),
subcategoryId: z.string().optional(),
sizeId: z.array(z.string()),
price: z.coerce.number().min(1),
brand: z.string().min(1),
isFeatured: z.boolean().default(false).optional(),
isArchived: z.boolean().default(false).optional(),
images: z.array(ProductImageSchema),
});
import { currentRole } from "@/hooks/use-current-role-server";
import { currentUser } from "@/hooks/use-current-user-server";
import { db } from "@/lib/db";
import { UserRole } from "@prisma/client";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
try {
const user = await currentUser();
const role = await currentRole();
const userId = user?.id;
const body = await req.json();
const {
name,
categoryId,
subcategoryId,
sizeId,
price,
brand,
isArchived,
isFeatured,
images,
} = body;
if (!userId) {
return new NextResponse("Unauthorized", { status: 401 });
}
if (role !== UserRole.ADMIN) {
return new NextResponse("Unauthorized", { status: 401 });
}
if (!name) {
return new NextResponse("Name is required", { status: 400 });
}
if (!categoryId) {
return new NextResponse("Category is required", { status: 400 });
}
if (!sizeId || sizeId.length === 0) {
return new NextResponse("Size is required", { status: 400 });
}
if (!price) {
return new NextResponse("Size is required", { status: 400 });
}
const product = await db.product.create({
data: {
name,
categoryId,
subcategoryId: subcategoryId || null,
sizeId,
price,
brand,
isArchived,
isFeatured,
images,
},
});
return NextResponse.json(product);
} catch (error) {
console.log("[PRODUCT_POST]", error);
return new NextResponse("Internal Error", { status: 500 });
}
}
如果您查看我的 Prisma 架构,您会注意到我希望子类别是可选的,因此?在它之后。如果您也查看 Zod 模式,您会注意到我也有 z.string.Optional() 但是当我尝试提交表单时,当未选择 subcategoryId 时,我会收到奇怪的错误,但它在选择时有效,所以我知道问题所在来自未选择的子类别我需要一个解决方案,因为我希望子类别是可选的
我通常遇到的错误
Invalid `prisma.product.create()` invocation:
{
data: {
name: "Sneakers",
categoryId: "6604bc28973d8ff95e7b4d44",
subcategoryId: null,
sizeId: [
"6600a1124992965a353051c2",
"6604b694973d8ff95e7b4d3a"
],
price: 30300,
brand: "Brand",
isArchived: false,
isFeatured: true,
images: [
{
colorId: "65f9a296f87aafb1836df2d5",
imageURLs: [
"https://res.cloudinary.com/dezuiqfsq/image/upload/v1711638173/ckrn1qi0bsdtfu8kn0zf.jpg"
]
}
],
+ category: {
+ create: CategoryCreateWithoutProductInput | CategoryUncheckedCreateWithoutProductInput,
+ connectOrCreate: CategoryCreateOrConnectWithoutProductInput,
+ connect: CategoryWhereUniqueInput
+ }
}
}
Argument `category` is missing.
at Cn (C:\Users\brian\Documents\Portfolio\cms\node_modules\@prisma\client\runtime\library.js:116:5888)
at _n.handleRequestError (C:\Users\brian\Documents\Portfolio\cms\node_modules\@prisma\client\runtime\library.js:123:6510)
at _n.handleAndLogRequestError
..................
}
您是正确的,
subcategory
模型上的 Product
可以为空,但 subcategoryId
(其上方的字段)则不能为空。就 Prisma 而言,您需要指定subcategoryId
字段来创建新的Product
。只需将 subcategoryId
设为可为空,就可以开始了!
subcategoryId String? @db.ObjectId