[23.11.01] TIL

yy·2023년 11월 1일

개발일지

목록 보기
19/122

오늘 할 일

  1. node.js 2주차 과제
    (완료) 1-1. ERD 만들기
    (완료) 1-2. 모델 만들기
    (완료) 1-3. 깃허브 백로그 만들기
  2. (->)node.js 강의 보기(쿠키, 세션, JWT)

🗞️ ERD만들기

이용한 사이트 : https://drawsql.app/diagrams
책 리뷰와 리뷰에 달리는 댓글 간의 관계를 만들어봤다.

Reviews table
(reivewsId, bookTitle, title, content, starRating, author, password, createdAt, updatedAt)

Comments table
(commentsId, ReviewsId, content, author, password, createdAt, updatedAt) comments의 외래키는 ReviewId 이다.

=> 책 리뷰 하나에 여러 개의 댓글이 달릴 수 있기때문에 1:N의 관계를 가진다.

둘의 테이블의 연관성은 테이블의 주체가 갖는 속성을 잘 생각해봐야해서 0과 1로 이루어진 세상속에서 말랑말랑한 인간세상에 나온 느낌이 든다. 🫠


👀모델 만들기(prisma)

위의 ERD을 참고하여 만든 schema.prisma

model Reviews {
  reviewsId  Int      @id @default(autoincrement()) @map("reviewsId")
  bookTitle  String   @map("bookTitle")
  title      String   @map("title")
  content    String   @map("content")
  starRating Int      @map("starRating")
  author     String   @map("author")
  password   Int      @map("password")
  createdAt  DateTime @default(now()) @map("createdAt")
  updatedAt  DateTime @updatedAt @map("updatedAt")
 
  Comments Comments[]
  @@map("Reviews")
}

model Comments {
  commentsId  Int      @id @default(autoincrement()) @map("commentsId")
  ReviewsId  Int      @map("ReviewsId")
  content    String   @map("content")
  author     String   @map("author")
  password   Int      @map("password")
  createdAt  DateTime @default(now()) @map("createdAt")
  updatedAt  DateTime @updatedAt @map("updatedAt")

  Reivew Reviews @relation(fields: [ReviewsId], references: [reviewsId], onDelete: Cascade)
  @@map("Comments")
}

여기서 중요한건 1:N 관계를 표현하는 방법이다. 그 외는 전날 TIL 살펴보면 나와있다.
우선 1:N에서 1인 Reviews 모델을 보면 다른거는 다 똑같고, 맨 아래에 Comments Comments[] 이 있다.
Reviews 테이블과 Comments이 1:N관계를 맺는다는 뜻이다. Comments[] 배열로 표시된 건 일대다의 관계를 표현한거라고 보면 된다.


그리고 Comments 에서 보면 맨 하단 부분에 있는 부분을 보면

Review Reviews @relation(fields: [ReviewsId], references: [reviewsId], onDelete: Cascade)

맨 앞 Review는 그냥 적어주는 모양이다. 이유를 모르겠음. 그 다음부터는 Reviews 테이블과의 관계`@relation`를 가진다는 뜻이다. 기존 SQL 문법과 좀 유사한데 fields에는 Comments에 있는 외래키를 넣어주고, references에는 Reviews에 있는 Comments와 연관되는 기본키를 넣어주면 된다. onDelete에 들어간 Cascade는 연쇄적으로 삭제한다는 뜻인데 만약 Reviews 테이블에 있는 데이터가 삭제되면 연관되어있는 Comments의 데이터도 같이 삭제된다는 뜻이다.

🦎 깃허브 백로그 만들기

프로젝트를 하다보면 백로그를 관리해야한다고 들었다. 백로그..?

  1. 깃허브에 들어가서 organization 을 만들어준다.


    2.organization을 만든 후 repository를 만들어준다.
  2. repository를 만들고, project를 만들어 진입한다.
  3. 들어가면 view가 여러가지가 있는데 거기서 만들어야하는 기능별이든...뭐든 만들어서 관리하면 된다.

    담당자, 기한, 만들 코드 크기 등을 지정할 수 있고, 잇슈등록, 마감도 가능하니 이용해보면 좋을듯 하다.

🫨delete에 관하여

api를 많이 만들지는 않았지만 기존에 만들었던 코드에서 코드리뷰를 받은게 있었다. delete메소드를 이용해서 데이터를 아예 삭제를 했는데 그렇게 되면 다시 정보를 되돌릴때 굉장히 힘들고, 정보관리가 안된다고 하셨다. (정보를 아예 삭제하는건 hard delete)
그럼 어떻게 해야하느냐! createdAt이나 updatedAt과 같이 작성날짜와 수정한 날짜를 관리하듯 deletedAt을 관리하면 된다고 하셨다.(soft delete)


띠요옹?! 🫨
deletedAt이라는 컬럼에 null을 허용하여 데이터를 생성할때 자동적으로 null이 입력되도록 한다. 그리고 삭제를 할 때 deletedAt의 현재 날짜가 찍히도록 한다.
그리고 목록조회할때는 deletedAt이 null인것만 조회되도록 하는 방법! 놀랄 노(浶)


그렇게 다시 코드를 수정해봤다.


//리뷰 삭제 API 코드 일부분
// await prisma.reviews.delete({ where: { reviewsId : +reviewsId, password }})
await prisma.reviews.update({
      data: { deletedAt: new Date() },
      where: { reviewsId: +reviewsId, password }
    });

다른 건 다 똑같고, 기존 delete 아예 삭제하는 코드 대신에 deletedAt부분을 new Date()로 값을 입력해준 부분을 추가했다.

//리뷰 목록 조회
router.get('/reviews', async (req, res, next) => {
  const reviews = await prisma.reviews.findMany({
    where: { deletedAt: null },
    select: {
      reviewsId: true,
      bookTitle: true,
      title: true,
      author: true,
      starRating: true,
      createdAt: true,
      updatedAt: true,
    }

그리고 더불어 리뷰 목록을 조회하는 부분에서 조건에 deletedAt이 null 인것만 조회하여 원하는 조건들만 찾도록 했다.

//리뷰 상세 조회
router.get('/reviews/:reviewsId', async (req, res, next) => {
  try {
    const { reviewsId } = req.params;

    const reviews = await prisma.reviews.findFirst({
      where: { reviewsId: +reviewsId },
      select: {
        reviewsId: true,
        bookTitle: true,
        title: true,
        content: true,
        author: true,
        starRating: true,
        createdAt: true,
        updatedAt: true,
        deletedAt: true
      }

진짜 deletedAt이 null인것만 조회가 되는건지 아닌지 확인하기위해서 상세 페이지에서만 확인하도록 했다. 목록에서 조회해서 보는거는 좀 별로라고 생각했기때문이다.


👊💥트러블슈팅

api를 만들면서 입력값이 제대로 들어왔는지 확인하는 반복되는 if문들이 이게 최선인가 하는 생각이 들었다. 그러다가 이거 함수로 만들어보면 어떨까
시도

  • 함수 안된다 젠장. 아니 내가 못하는걸수도

할 거

  • starRating 조이로 받는다면 => joi 에러메시지 커스텀
  • 조이 안쓰면 if문으로 에러 처리
profile
시간이 걸릴 뿐 내가 못할 건 없다.

0개의 댓글