대댓글 DB 구성
댓글과 대댓글을 구현하기 위해선 DB에 필수적으로 필요한 칼럼이 존재한다.
- com_idx : 댓글 및 대댓글을 구분할 auto increment 속성의 칼럼`
- com_group : 대댓글의 상위 댓글(대댓글)의 com_idx이며 대댓글 이하의 대댓글을 로딩할 때 사용
- depth : 댓글의 깊이를 지정함

이 외에 부가적인 다른 요소들을 더 추가해 위 사진과 같은 테이블을 형성하였다.

위 사진은 댓글 기능이 적용될 problem 페이지이며 댓글 부분의 내부 로직은 다음과 같다.
<!-- problem.ejs -->
<% function renderComments(commentContent, comGroup=0, depth=0) { %>
<% for (let i=0; i < posts.commentContent.length; i++) { %>
<% if (commentContent[i].com_group==comGroup) { %>
<div class="comment reply" id="comment-<%= posts.commentContent[i].com_idx %>" tabindex="0">
<span class="author">
<li>
<%= commentContent[i].usr_id %>
<!-- Reply button -->
<button type="button" class="comment-action-btn" onclick="toggleReplyForm(this, '<%= commentContent[i].com_idx %>')">Reply</button>
<!-- Edit button -->
<% if (posts.currentUsrId==commentContent[i].usr_id) { %>
<button type="button" class="comment-action-btn" onclick="toggleEditForm(this, '<%= commentContent[i].com_idx %>')">Edit</button>
<% } %>
<!-- Delete button -->
<% if (posts.currentUsrClass==1 || posts.currentUsrId==commentContent[i].usr_id) { %>
<button type="button" id="deleteCommentBtn" class="comment-action-btn" onclick="if(confirm('Are you sure you want to delete this?')){toggleDeleteForm('<%= commentContent[i].com_idx %>')}">Delete</button>
<% } %>
</li>
</span>
<p>
<%= commentContent[i].text %>
</p>
<span class="time">
<%= new Date(commentContent[i].com_time).toLocaleDateString('ko-KR', { year: 'numeric' , month: 'long' , day: 'numeric' }) %>
<%= new Date(commentContent[i].com_time).toLocaleTimeString('ko-KR', { hour: '2-digit' , minute: '2-digit' }) %>
</span>
<!-- Reply form (initially hidden) -->
<div class="reply-form-container" style="display:none;"
id="reply-form-<%= posts.commentContent[i].com_idx %>">
<form method="post" action="./problem/comment" class="reply-form">
<input type="hidden" name="com_idx" value="<%= commentContent[i].com_idx %>">
<input type="hidden" name="pro_idx" value="<%= commentContent[i].pro_idx %>">
<input type="hidden" name="depth" value="<%= posts.commentContent[i].depth + 1 %>">
<input type="hidden" name="usr_idx" value="<%= posts.currentUsrIdx.usr_idx %>">
<input type="text" name="comment" placeholder="Enter your reply...">
<button type="submit">Reply</button>
</form>
</div>
<!-- Edit form (initially hidden) -->
<div class="edit-form-container" style="display:none;"
id="edit-form-<%= posts.commentContent[i].com_idx %>">
<form method="post" action="./problem/comment/edit" class="edit-form">
<input type="hidden" name="comIdx" value="<%= commentContent[i].com_idx %>">
<input type="text" name="editText" value="<%= commentContent[i].text %>">
<button type="submit">Edit</button>
</form>
</div>
<% renderComments(commentContent, commentContent[i].com_idx, depth + 1); %>
</div>
<% } %>
<% } %>
<% } %>
<% if (posts.countComment > 0) { %>
<div class="content">
<div class="comments-list">
<% renderComments(posts.commentContent, 0, 0); %>
</div>
</div>
<% } %>
problem 페이지의 일부 ejs 코드이다. 컨트롤러 파일에선 comments 테이블에 관한 정보를 ejs 파일로 넘겨주는데
ejs 파일의 renderComments 함수는 이 정보를 받아 재귀적으로 함수를 실행시키게 되며
com_group와 depth로 댓글을 DB 내에서 검색해서 이를 반환한다.

따라서 위 형식으로 댓글이 구성되게 된다.
'Dev' 카테고리의 다른 글
Dockerfile 생성하기 (0) | 2025.02.27 |
---|---|
비밀번호 초기화 이메일 보내기 구현 (0) | 2025.02.27 |
파일 업로드, 다운로드 기능 추가 (0) | 2025.02.27 |
로그인 기능 구현 (0) | 2025.02.27 |
node.js 회원가입 로직 구현 (0) | 2025.02.27 |