NestJS-Follow count

jaegeunsong97·2024년 2월 23일
0

NestJS

목록 보기
37/37

🖊️Follow Count increment & decrement

팔로우를 누른 경우, 팔로우 요청 또는 팔로우 삭제 경우에만 count를 조절하도록 하겠습니다.

트랜젝션을 사용해서 구현을 해보겠습니다. 먼저 count를 담당할 컬럼을 만들겠습니다.

  • users.entity.ts
.
.
@Column({
  	default: 0
})
followerCount: number;

@Column({
  	default: 0
})
followeeCount: number;
  • users.controller.ts
@Patch('follow/:id/confirm') // 나를 팔로우 하려는 상대 id
@UseInterceptors(TransactionInterceptor)
async patchFollowConfirm(
    @User() user: UsersModel,
    @Param('id', ParseIntPipe) followerId: number,
    @QueryRunner() qr: QR,
) {
    await this.usersService.confirmFollow(followerId, user.id, qr);
    await this.usersService.incrementFollowerCount(user.id, qr);
    return true;
}

@Delete('follow/:id')
@UseInterceptors(TransactionInterceptor)
async deleteFollow(
    @User() user: UsersModel,
    @Param('id', ParseIntPipe) followeeId: number, // 내가 팔로우하는 상대
    @QueryRunner() qr: QR,
) {
    await this.usersService.deleteFollow(user.id, followeeId, qr);
    await this.usersService.decrementFollowerCount(user.id, qr);
    return true;
}
  • users.service.ts
getUsersRepository(qr?: QueryRunner) {
  // qr 있는 경우
  return qr ? qr.manager.getRepository<UsersModel>(UsersModel) : this.usersRepository;
}
     
getUsersFollowRepository(qr?: QueryRunner) {
  // qr 있는 경우
  return qr ? qr.manager.getRepository<UserFollowersModel>(UserFollowersModel) : this.userFollowersRepository;
}
.
.
async followUser(followerId: number, followeeId: number, qr?: QueryRunner) {
    const userFollowersRepository = this.getUsersFollowRepository(qr);
    await userFollowersRepository.save({
        follower: {
          	id: followerId
        },
        followee: {
          	id: followeeId
        }
    });

    return true;
}
.
.
async confirmFollow(followerId: number, followeeId: number, qr?: QueryRunner) {
    const userFollowersRepository = this.getUsersFollowRepository(qr);

    // 중간테이블에 데이터가 존재하는지 확인
    const existing = await userFollowersRepository.findOne({
        where: {
            follower: {
              	id: followerId
            },
            followee: {
              	id: followeeId
            }
        },
        relations: {
            follower: true,
            followee: true
        },
    });
    if (!existing) throw new BadRequestException(`존재하지 않는 팔로우 요청입니다. `);

    // save값을 넣으면, 변경된 부분만 update한다.
    await userFollowersRepository.save({
        ...existing,
        isConfirmed: true,
    });
    return true;
}
.
.
async deleteFollow(followerId: number, followeeId: number, qr?: QueryRunner) {
    const userFollowersRepository = this.getUsersFollowRepository(qr);
    await userFollowersRepository.delete({
        follower: {
          	id: followerId,
        },
        followee: {
          	id: followeeId,
        },
    });
    return true;
}
.
.
async incrementFollowerCount(userId: number, qr?: QueryRunner) {
    const userRepository = this.getUsersRepository(qr);
    await userRepository.increment({
      	id: userId
    }, 'followerCount', 1);
}

async decrementFollowerCount(userId: number, qr?: QueryRunner) {
    const userRepository = this.getUsersRepository(qr);
    await userRepository.decrement({
      	id: userId
    }, 'followerCount', 1);
}

테스트를 진행해보겠습니다.

현재 1번 사용자로 2번사용자를 팔로우하고 1번사용자가 요청을 수락하면 2번 사용자의 follwer는 1증가합니다. 하지만 1번 사용자의 follwee는 0 그대로 존재합니다.

이 문제를 해결해보겠습니다.

{{추가 필요!!!!!!!!!!!!!!}}


🖊️Comment Count

  • posts.service.ts
async incrementCommentCount(postId: number, qr?: QueryRunner) {
    const repository = this.getRepository(qr);
    await repository.increment({
      	id: postId,
    }, 'commentCount', 1);
}

async decrementCommentCount(postId: number, qr?: QueryRunner) {
    const repository = this.getRepository(qr);
    await repository.decrement({
      	id: postId,
    }, 'commentCount', 1);
}
  • comments.service.ts
.
.
getRepository(qr?: QueryRunner) {
	return qr ? qr.manager.getRepository<CommentsModel>(CommentsModel) : this.commentsRepository;
}
.
.
async createComment(
    dto: CreateCommentsDto,
    postId: number,
    author: UsersModel,
    qr?: QueryRunner,
) {
    const repository = this.getRepository(qr);
    return repository.save({
        ...dto,
        post: {
          	id: postId
        },
        author,
    });
}
.
.
async deleteComment(
    id: number,
    qr?: QueryRunner
) {
    const repository = this.getRepository(qr);
    const comment = await repository.findOne({
        where: {
          	id,
        }
    });
    if (!comment) throw new BadRequestException(`존재하지 않는 댓글입니다. `);
    await repository.delete(id);
    return id;
}
  • comments.controller.ts
@Post()
@UseInterceptors(TransactionInterceptor)
async postComment(
    @Param('postId', ParseIntPipe) postId: number,
    @Body() body: CreateCommentsDto,
    @User() user: UsersModel,
    @QueryRunner() qr: QR,
) {
    const resp = await this.commentsService.createComment(
        body, 
        postId, 
        user,
        qr
    );
    await this.postsService.incrementCommentCount(
        postId,
        qr
    );

    return resp;
}
.
.
@Delete(':commentId')
@UseInterceptors(TransactionInterceptor)
@UseGuards(IsCommentMineOrAdminGuard)
async deleteComment(
    @Param('commentId', ParseIntPipe) commentId: number,
    @Param('postId', ParseIntPipe) postId: number, // endpoint에서 받아옴
    @QueryRunner() qr: QR,
) {
    const resp = await this.commentsService.deleteComment(
      commentId,
      qr
    );
    await this.postsService.decrementCommentCount(postId, qr);
    return resp;
}
profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글