내일배움캠프 TIL (230322): Typeorm softDelete된 값을 가져오지 못함

Jiumn·2023년 4월 2일
0

Typeorm softDelete된 값을 가져올 때 문제

강사가 워크샵 문의를 반려(=수강 취소)하면 해당 워크샵 문의를 테이블에서 softDelete하기로 했다.
현재는 유저가 마이페이지에서 수강 예정 / 수강 완료된 워크샵 목록만 볼 수 있지만, 수강 취소된 내역까지 보게 하려면 softDelete된 값, 즉 DeletedAt이 null이 아닌 값도 가져와야 하는 것이다.
(softDelete는 컬럼을 삭제하지 않는 대신 DeletedAt 컬럼에 삭제 시간을 기록하는 논리적 삭제 방식이다.)

처음에는 단순하게 where 조건으로 DeleteadAt 컬럼이 null이 아닌 값도 select하려고 했으나 작동되지 않았다.

softDelete된 컬럼만 따로 불러오려고 팀원들과 1시간 넘게 온갖 코드를 다 작성해봤지만...
logger를 통해 콘솔에 찍힌 sql 쿼리문을 보니, 쿼리문 끝에는 항상 DeletedAt is null 이라는 쿼리가 붙는 것을 확인할 수 있었다. 그래서 DeletedAt is not null인 값과는 양립할 수 없어서(?) softDelete된 값을 가져오지 못하는 것 같았다.

withDeleted() 메소드를 써봐도 적용이 안 됐다.
어느 블로그에서 결국 softDelete() 메소드를 사용하지 않고
deletedAt이라는 컬럼을 따로 만들어서 데이터 삭제 시에 update() 메서드로 현재 시간을 넣어줬다는 글을 보기는 했으나
우리는 결국 status 값을 더 추가해서 rejected 상태의 것을 불러오기로 했다

왜 적용이 안되는지는 모르겠다. (typeorm 0.3.0 이상 버전의 이슈인지...?)

WHERE IN 문법 사용하기

수강 환불 또는 취소인 데이터 (status가 refund 또는 rejected)인 데이터들을 불러오려고 할 때 orWhere로 적용하면 될 줄 알았는데 정상 작동하지 않았다.

// 수강 취소 워크샵 전체 조회 API
  async getRefundWorkshops(user_id: number) {
    try {
      const workshops = await this.workShopInstanceDetailRepository
        .createQueryBuilder('workshopDetail')
        .innerJoinAndSelect('workshopDetail.Workshop', 'workshop')
        .where('workshopDetail.user_id = :id', { id: user_id })
        .andWhere('workshopDetail.status IN (:...status)', {
          status: ['refund', 'rejected'],
        })
        .select([
          'workshop.id',
          'workshop.thumb',
          'workshop.title',
          'workshopDetail.status',
          'workshopDetail.wish_date',
          'workshopDetail.member_cnt',
          'workshopDetail.id',
        ])
        .getRawMany();

      // s3 + cloud front에서 이미지 가져오기
      const cloundFrontUrl = this.configService.get(
        'AWS_CLOUD_FRONT_DOMAIN_IMAGE',
      );

      // request, non_payment, waiting_lecture만 필터링 + thumbUrl 가공
      const canceledWorkshops = workshops.map((workshop) => ({
        ...workshop,
        thumbUrl: `${cloundFrontUrl}images/workshops/${workshop.workshop_id}/800/${workshop.workshop_thumb}`,
      }));

      return canceledWorkshops;
    } catch (err) {
      throw err;
    }
  }

결국 다음과 같이 WHERE IN (...) 문법을 사용했다.

        .andWhere('workshopDetail.status IN (:...status)', {
          status: ['refund', 'rejected'],
        })

where in 문법을 사용하면 where 조건을 여러 개를 or 조건으로 줄 수 있다.
컬럼의 조건들을 배열로 만들어서 값이 해당 배열 안과 일치하는지 확인하는 형식이다.

profile
Back-End Wep Developer. 꾸준함이 능력이다. Node.js, React.js를 주로 다룹니다.

0개의 댓글