3-10. 추천 기능 추가하기

좋아요, 추천 기능을 구현할 수 있다.

엔티티에 속성 추가하기

‘추천’ 기능을 구현하려면 질문이나 답변을 추천한 사용자(SiteUser)가 DB에 저장될 수 있도록 관련 속성을 질문, 답변 엔티티에 추가해야 한다.

voter: 추천인에 대한 속성. 한 사람이 여러 개의 질문을 추천할 수 있도록 @ManyToMany를 사용해야 한다.

	//Question, Answer에 voter 속성 추가
	import java.util.Set;
	import jakarta.persistence.ManyToMany;
	
	@ManyToMany
	Set<SiteUser> voter;

H2 콘솔에 voter 속성이 추가된 것을 확인할 수 있다.

@ManyToMany 애너테이션을 사용해 다대다 관계로 속성이 생성이 되어 새로운 테이블이 만들어진 것을 확인할 수 있다.

Untitled

추천 기능 생성하기

<!-- question_detail.html 의 게시글, 답변 부분 추가 -->
<a href="javascript:void(0);" class="recommend btn btn-sm btn-outline-secondary"
		th:data-uri="@{|/question/vote/${question.id}|}">
		추천
		<span class="badge rounded-pill bg-success" th:text="${#lists.size(question.voter)}"></span>
</a>
<a href="javascript:void(0);" class="recommend btn btn-sm btn-outline-secondary"
		th:data-uri="@{|/answer/vote/${answer.id}|}">
		추천
		<span class="badge rounded-pill bg-success" th:text="${#lists.size(answer.voter)}"></span>
</a>
<!-- script 부분에 추가-->
	const recommend_elements = document.getElementsByClassName("recommend");
	Array.from(recommend_elements).forEach(function (element) {
		element.addEventListener('click', function () {
			if (confirm("정말로 추천하시겠습니까?")) {
				location.href = this.dataset.uri;
			};
		});
	});
//QuestionService.java 에 추가
	public void vote(Question question, SiteUser siteUser) {
		question.getVoter().add(siteUser);
		this.questionRepository.save(question);
	}
//QuestionController.java 에 추가
	@PreAuthorize("isAuthenticated()")
	@GetMapping("/vote/{id}")
	public String questionVote(Principal principal, @PathVariable("id") Integer id) {
		Question question = this.questionService.getQuestion(id);
		SiteUser siteUser = this.userService.getUser(principal.getName());
		this.questionService.vote(question, siteUser);
		return String.format("redirect:/question/detail/%s", id);
	}
//AnswerService.java 에 추가
	public void vote(Answer answer, SiteUser siteUser) {
		answer.getVoter().add(siteUser);
		this.answerRepository.save(answer);
	}
//AnswerController.java 에 추가
	@PreAuthorize("isAuthenticated()")
	@GetMapping("/vote/{id}")
	public String answerVote(Principal principal, @PathVariable("id") Integer id) {
		Answer answer = this.answerService.getAnswer(id);
		SiteUser siteUser = this.userService.getUser(principal.getName());
		this.answerService.vote(answer, siteUser);
		return String.format("redirect:/question/detail/%s", answer.getQuestion().getId());
	}

Untitled

Untitled

3-11. 앵커 기능 추가하기

앵커(anchor): URL 호출 시 원하는 위치로 이동해 주는 <a> 태그 기능.

답변을 작성하거나 수정할 때 redirect가 되면서 페이지가 상단으로 올라가지는 현상을 보완하기 위한 기능.

답변 앵커 추가하기

<!-- question_detail.html 에 추가-->
	<!-- 답변 반복 시작 -->
	<div class="card my-3" th:each="answer : ${question.answerList}">
		<a th:id="|answer_${answer.id}|"></a>
		<div class="card-body">