댓글을 삭제할 수 있는 사람은 2명 뿐이다(관리자는 제외).
그 외에는 댓글을 삭제할 수 없다. 위 로직을 어떻게 만들었는지 설명하는 글이다.
@Transactional
public void delete(Long commentId, UserDetails userDetails) {
Comment comment = commentRepository.findById(commentId).orElseThrow(NoCommentFoundException::new);
User user = userRepository.findByUsername(userDetails.getUsername()).orElseThrow(NoUserFoundException::new);
if(user.hasNoRightToChange(comment)) {
throw new InvalidCommentUpdateRequestException();
}
commentRepository.delete(comment);
}
댓글 삭제 로직 구현부이다. 중간 if 조건에서 유저가 댓글을 삭제할 권한이 없다면 예외를 던지고 있다.
public boolean hasNoRightToChange(Comment comment) {
return !comment.getUser().getId().equals(this.getId()) && !comment.getVideo().getUser().getId().equals(this.getId());
// 커멘트 작성자의 아이디와 이 유저의 아이디가 일치하지 않는다면 && 댓글이 달린 비디오의 주인 아이디가 이 유저와 일치하지 않는다면
}
유저 엔티티 내부에서 댓글 수정 권한이 있는지 확인하는 메서드이다. 메서드 이름처럼 TRUE 라면 댓글을 수정할 수 있는 권한이 없다.
엔티티 주도로 로직이 흘러야 읽기 좋은 코드라고 생각하기 때문에 개인적으로 엔티티에 메서드를 많이 만드는 편이다. 개인적인 취향이므로 다른 방법으로도 얼마든지 제작 가능하다.
@Getter
public class CommentDto {
private final Long id;
private final String content;
private final String author;
private final LocalDateTime createdAt;
private final Boolean isAuthor;
private final Boolean isVideoOwner;
}
위 조건을 만족하는지 프론트에도 표시해줘야 하기 때문에 댓글 DTO에 관련한 필드를 생성하였다. DTO에서는 위 조건에 일치하는지 어떻게 확인하냐고? 아래와 같다.
public static CommentDto of(Comment comment, String currentUserName) {
return CommentDto.builder()
.id(comment.getId())
.content(comment.getContent())
.author(comment.getUser().getNickname())
.createdAt(comment.getCreatedAt())
.isAuthor(currentUserName.equals(comment.getUser().getUsername()))
// 지금 로그인한 유저가 댓글 작성자인지 확인
.isVideoOwner(currentUserName.equals(comment.getVideo().getUser().getUsername()))
// 지금 로그인한 유저가 비디오 주인인지 확인
.build();
}
DTO 생성 메서드이다(개인적으로 DTO.of(Entity)
형식의 구조를 좋아한다). 로그인한 유저의 이름을 받아서 댓글의 정보와 비교한다. true라면 프론트에서 해당 댓글을 수정할 수 있는 버튼이 보이도록 설계했다.
위 경우가 아니라면 프론트에서는 해당 댓글의 수정/삭제 버튼을 출력하지 않아야한다.
<div v-if="comment.isAuthor || comment.isVideoOwner" class="mt-1">
<button @click="startEditing(comment.id, comment.content)" class="btn btn-outline-primary btn-sm me-2">수정</button>
<button @click="deleteComment(comment.id)" class="btn btn-outline-danger btn-sm">삭제</button>
</div>
v-if 부분에서 댓글의 작성자 이거나 댓글의 비디오 주인인지 확인한다. 그리고 해당 조건을 만족하면 수정/삭제 버튼이 출력된다.