Search code examples
next.jsprismasupabasezod

How to make a Prisma list field optional?


enter image description here // schema.prisma before

model Product {
id           String          @id @default(uuid())
storeId      String
store        Store           @relation("StoreToProduct", fields: 
[storeId], references: [id])
categoryId   String 
category     Category     @relation("CategoryToProduct", fields: 
[categoryId], references:[id])
name         String
price        Decimal
sizeId       String
size         Size            @relation(fields: [sizeId], 
references: [id])
colorId      String
color        Color           @relation(fields: [colorId], 
references: [id])
images       Image[]
saleItems    SaleItem[]
createdAt    DateTime        @default(now())
updatedAt    DateTime        @updatedAt

@@index([storeId])
@@index([categoryId])
@@index([sizeId])
@@index([colorId])

}

// schema.prisma after

model Product {
id           String          @id @default(uuid())
storeId      String
store        Store           @relation("StoreToProduct", fields: 
[storeId], references: [id])
categoryId   String 
category     Category     @relation("CategoryToProduct", fields: 
[categoryId], references:[id])
name         String
price        Decimal
sizeId       String?
size         Size?         @relation(fields: [sizeId], 
references: [id])
colorId      String?
color        Color?           @relation(fields: [colorId], 
references: [id])
images       Image[]
saleItems    SaleItem[]
createdAt    DateTime        @default(now())
updatedAt    DateTime        @updatedAt

@@index([storeId])
@@index([categoryId])
@@index([sizeId])
@@index([colorId])

}

// product-form.tsx

const form = useForm<ProductFormValues>({
 resolver: zodResolver(formSchema),
 defaultValues: initialData
  ? {
      ...initialData,
      price: parseFloat(String(initialData?.price)),
    }
  : {
      name: "",
      images: [],
      price: 0,
      categoryId: "",
      colorId: "",
      sizeId: "",
      isFeatured: false,
      isArchived: false,
    },
});
[![defaultValues error][1]][1]

I am building a NextJS App with Prisma, and I have the above Prisma model that I would like to make the sizeId and the colorId as optional items for the Product form, and I do not know how to do it with Prisma(Some say it is not possible). Thanks in advance.

Update: I have been able to make my sizeId and colorId optional(I think), but now I am getting an error from my defaultValues of the form saying the values are not assignable to the defaultValues


Solution

  • Here’s how you can update your code to handle optional fields properly:

    1. Update the Prisma Model: Ensure sizeId and colorId are optional by marking them with '?'
    model Product {
      id           String    @id @default(uuid())
      storeId      String
      store        Store     @relation("StoreToProduct", fields: [storeId], references: [id])
      categoryId   String
      category     Category  @relation("CategoryToProduct", fields: [categoryId], references:[id])
      name         String
      price        Decimal
      sizeId       String?
      size         Size?     @relation(fields: [sizeId], references: [id])
      colorId      String?
      color        Color?    @relation(fields: [colorId], references: [id])
      images       Image[]
      saleItems    SaleItem[]
      createdAt    DateTime  @default(now())
      updatedAt    DateTime  @updatedAt
    
      @@index([storeId])
      @@index([categoryId])
      @@index([sizeId])
      @@index([colorId])
    }
    
    1. Ensure Correct Types in TypeScript: Update your 'ProductFormValues' type in TypeScript to reflect that 'sizeId' and 'colorId' can be either 'string' or 'undefined'.
    type ProductFormValues = {
      name: string;
      images: string[];
      price: number;
      categoryId: string;
      colorId?: string;
      sizeId?: string;
      isFeatured: boolean;
      isArchived: boolean;
    };
    
    1. Default Values in Form Initialization: Update the defaultValues to handle optional fields properly.
    const form = useForm<ProductFormValues>({
      resolver: zodResolver(formSchema),
      defaultValues: initialData
        ? {
            ...initialData,
            price: parseFloat(String(initialData?.price)),
            colorId: initialData.colorId || undefined,
            sizeId: initialData.sizeId || undefined,
          }
        : {
            name: "",
            images: [],
            price: 0,
            categoryId: "",
            colorId: undefined,
            sizeId: undefined,
            isFeatured: false,
            isArchived: false,
          },
    });
    

    With the above adjustments, hope that your problem will be fixed.