팔로우를 누른 경우, 팔로우 요청 또는 팔로우 삭제 경우에만 count를 조절하도록 하겠습니다.
트랜젝션을 사용해서 구현을 해보겠습니다. 먼저 count를 담당할 컬럼을 만들겠습니다.
.
.
@Column({
default: 0
})
followerCount: number;
@Column({
default: 0
})
followeeCount: number;
@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;
}
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 그대로 존재합니다.
이 문제를 해결해보겠습니다.
{{추가 필요!!!!!!!!!!!!!!}}
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);
}
.
.
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;
}
@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;
}
Useful knowledge and worth learning. Enjoy having exciting experiences. Please continue to update and share information sources. Besides, expand and improve your knowledge even more basketbros