라이브러리, 프레임워크/TypeORM

[TypeORM + NestJS] 일기 생성 API - oneToMany, manyToMany save 로직 기록

dv_jamie 2023. 1. 1. 22:24

개요

  • 하나의 일기에 여러 개의 이미지들과 테마들을 함께 등록할 수 있음
  • 일기, 이미지, 테마는 각각 테이블을 하나씩 갖고 있음
  • 테마는 유저가 수정할 수 없는 값으로, 데이터들을 미리 저장해뒀음

 

관계 설정

  • 일기와 이미지 : OneToMany (하나의 일기에 여러 개의 이미지 등록 가능)
  • 일기와 테마 : ManyToMany (각 일기는 여러개의 테마, 각 테마는 여러 개의 일기를 가질 수 있음)

 

일기 생성 API

// create-diary.dto.ts

import { PickType } from "@nestjs/mapped-types";
import { IsNumber, IsString } from 'class-validator';
import { Diary } from "../entities/diary.entity";

export class CreateDiaryDto extends PickType(Diary, [
    // 유저가 입력하는 일기의 내용
    'content',
] as const) {
    // 테마는 이미 등록되어 있으므로 유저가 선택한 테마 id를 배열로 받을 수 있음
    @IsNumber({}, { each: true })
    themeIds: number[]

    // 이미지는 url을 배열로 받음
    @IsString({ each: true })
    imageUrls: string[]
}
// diaries.service.ts

  async create(
    reqId: number, // 작성자는 request 객체로 받음
    createDiaryDto: CreateDiaryDto
  ):Promise<ResponseDto> {
    const findWriter = await this.usersService.findOneById(reqId)
    const writer = findWriter.data
    const { content, themeIds, imageUrls } = createDiaryDto

    // diary 엔티티에서 themes: Theme[]로 타입을 지정함
    // 테마를 엔티티로 저장 + 해당 테마 없을 경우의 예외 처리 위해
    // id값으로 theme 엔티티를 find
    const themes:Theme[] = []
    for(const id of themeIds) {
      const theme = await this.themesService.findOneById(id)
      themes.push(theme)
    }

    // 위에서 만든 Theme 엔티티 배열을 아래와 같이 함께 save하여 일기 생성
    const createdDiary = await this.diaryRepository.save({
      content,
      writer,
      themes
    })

    // Image 객체 생성 후 url과 위에 생성했던 diary를 담아 save
    for(const url of imageUrls) {
      const newImage = new Image 
      newImage.url = url
      newImage.diary = createdDiary
      await this.imagesService.create(newImage) // create 함수는 아래 코드블럭 참고
    }

    return {
      status: 200,
      data: {}
    };
  }
// images.service.ts

async create(image: Image) {
    const createdImages = await this.imageRepository.save(image)
    return createdImages
}

 


참고 블로그