Zichzheng
Zichzheng

Reputation: 1280

NestJS-Prisma, How to write a DTO that matches the prisma one to many type

I'm new to NestJS and Prisma. I'm trying to write an API for the corresponding prisma model.

Here is my prisma model:

    model orderable_test {
      id                 Int               @id @unique @default(autoincrement())
      test_name          String
      test_id            Int
      price              Int
      is_orderable       Boolean
      is_active          Boolean
      orderable_bundle   orderable_bundle? @relation(fields: [orderable_bundleId], references: [id])
      orderable_bundleId Int?
    }
    
    model orderable_bundle {
      id              Int              @id @unique @default(autoincrement())
      bundle_name     String
      bundle_id       Int
      price           Int
      is_orderable    Boolean
      is_active       Boolean
      orderable_tests orderable_test[]
    }

For the orderable_test, my DTO works well, the DTO for orderable_test is:

class OrderableTestDTO {

    @ApiProperty()
    test_name: string;
    @ApiProperty()
    test_id: number;
    @ApiProperty()
    price: number;
    @ApiProperty()
    is_orderable: boolean;
    @ApiProperty()
    is_active: boolean;
    @ApiPropertyOptional({default: null})
    orderable_bundleId:number|null;
}

For the orderable_bundle DTO, I have

class OrderableBundleDTO {
    @ApiProperty()
    bundle_name: string;
    @ApiProperty()
    bundle_id: number;
    @ApiProperty()
    price: number;
    @ApiProperty()
    is_orderable: boolean;
    @ApiProperty()
    is_active: boolean;
    @ApiPropertyOptional({type: () => OrderableTestDTO})
    orderable_tests: OrderableTestDTO | null
}

Based on the Prisma Official Document: I will need my DTO to be like

const createBundle = await prisma.bundle.create({
  data: {
    bundle_name: 'Bob',
    bundle_id: 1
    ............
    orderable_tests: {
      create: [
        {
          id: 'String',
          test_name: 'String',
          test_id: 1,
      price: 0
          .....
        },
      ],
    },
  },
})

But currently, my DTO will be look like this: missing the create:

const createBundle = await prisma.bundle.create({
  data: {
    bundle_name: 'Bob',
    bundle_id: 1
    ............
    orderable_tests: 
        {
          id: 'String',
          test_name: 'String',
          test_id: 1,
      price: 0
          .....
        },

    },
  },
})

And for the auto generated Prisma type: It looks like:

  export type orderable_bundleCreateInput = {
    bundle_name: string
    bundle_id: number
    price: number
    is_orderable: boolean
    is_active: boolean
    orderable_tests?: orderable_testCreateNestedManyWithoutOrderable_bundleInput
  }

  export type orderable_testCreateNestedManyWithoutOrderable_bundleInput = {
    create?: XOR<Enumerable<orderable_testCreateWithoutOrderable_bundleInput>, Enumerable<orderable_testUncheckedCreateWithoutOrderable_bundleInput>>
    connectOrCreate?: Enumerable<orderable_testCreateOrConnectWithoutOrderable_bundleInput>
    createMany?: orderable_testCreateManyOrderable_bundleInputEnvelope
    connect?: Enumerable<orderable_testWhereUniqueInput>
  }

I'm really new into type script and prisma, is it possible to have a DTO that looks exactly to the auto genenated prisma type, if not, how can I add the create: before my inner orderable_test under the orderable_bundle DTO. Thanks for viewing my question!

Upvotes: 4

Views: 13652

Answers (1)

Zichzheng
Zichzheng

Reputation: 1280

I just figured it out myself. I can adapt the similar format from the automatic generated prisma type to a DTO.

For example, I was trying to match a prisma type like this:

  export type orderable_bundleUncheckedCreateInput = {
    id?: number
    bundle_name: string
    bundle_id: number
    price: number
    is_orderable: boolean
    is_active: boolean
    order_infoId?: number | null
    orderable_tests?: orderable_testUncheckedCreateNestedManyWithoutOrderable_bundleInput
  }

  export type orderable_testUncheckedCreateNestedManyWithoutOrderable_bundleInput = {
    create?: XOR<Enumerable<orderable_testCreateWithoutOrderable_bundleInput>, Enumerable<orderable_testUncheckedCreateWithoutOrderable_bundleInput>>
    connectOrCreate?: Enumerable<orderable_testCreateOrConnectWithoutOrderable_bundleInput>
    createMany?: orderable_testCreateManyOrderable_bundleInputEnvelope
    connect?: Enumerable<orderable_testWhereUniqueInput>
  }

  export type orderable_testCreateWithoutOrderable_bundleInput = {
    test_name: string
    test_id: number
    price: number
    is_orderable: boolean
    is_active: boolean
  }
  .........

This type can let me choose to either create or connect to the other models I set relations with when creating this data.

For the DTO, I can write this one to match:

import {ApiExtraModels,ApiProperty} from '@nestjs/swagger'
import {CreateOrderInfoDto} from './create-orderInfo.dto'
import {ConnectOrderInfoDto} from './connect-orderInfo.dto'

export class CreateOrderableBundleOrderInfoRelationInputDto {
create?: CreateOrderInfoDto;
connect?: ConnectOrderInfoDto;
}

@ApiExtraModels(CreateOrderInfoDto,ConnectOrderInfoDto,CreateOrderableBundleOrderInfoRelationInputDto)
export class CreateOrderableBundleDto {
@ApiProperty()
bundle_name: string;
@ApiProperty()
bundle_id: number;
@ApiProperty()
price: number;
@ApiProperty()
is_orderable: boolean;
@ApiProperty()
is_active: boolean;
@ApiProperty()
order_info: CreateOrderableBundleOrderInfoRelationInputDto;
}

export class CreateOrderInfoDto {
sample_id: number;
sample_barcode: number;
}

  export class ConnectOrderInfoDto {
id?: number;
sample_id?: number;
sample_barcode?: number;
  }

Upvotes: 3

Related Questions