좋아요 기능 구현

알파로그·2023년 3월 24일
0

Spring Boot

목록 보기
29/57
post-custom-banner

✏️ 구현 전 Entity 상태

  • SiteUser
    • 클라이언트의 정볼를 저장
  • Question
    • User 게시물의 정보를 저장
  • Answer
    • Question 의 댓글을 저장

📍 연관관계 다이어그램

✏️ 좋아요 기능 설계

  • 좋아요 기능을 추가하기 위해서 SiteUser 의 참조를 하나 더 추가해야 한다.
    • 글쓴이와 답변자는 1:N , N:1 의 관계지만,
      좋아요는 N:N 의 관계이다.
      - 하나의 질문에 여러 SiteUser 가 좋아요를 누를 수 있음
      - 한명의 SiteUser 가 여러 질문에 좋아요를 누를 수 있음

✏️ Entity 속성 추가

  • Qustion, Answer 에 @ManyToMany 어노테이션을 붙여준다.
    • 실무에서는 @ManyToMany 를 사용하지 않기 때문에 참고만하자
    @ManyToMany
    Set<SiteUser> voter;

✏️ Web 계층 - 좋아요 버튼 추가

  • 버튼과 좋아요 숫자도 함께 보이도록 구현
  • javascript
    • 버튼을 누르면 안내 메시지가 나타나게 구현
    • 사실상 삭제버튼에 사용했던 로직과 동일하다.
<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>

    //-- 좋아요 버튼 관련 로직 --//
    const recommend_elements = document.getElementsByClassName("recommend");

    Array.from(recommend_elements).forEach(function (element) {
        element.addEventListener("click", function () {
            if (confirm("정말로 추천하시겠습니까?")) {
                location.href = this.dataset.uri;
            }
        });
    });

✏️ Service 계층 - 좋아요 추가 기능

  • Entity 의 voter 필드에 user 를 추가
    • 중복을 막기 위해서 Set 으로 되어있다.
@Service
@RequiredArgsConstructor
public class QuestionService {

    private final QuestionRepository questionRepository;

    //-- 좋아요 추가 --//
    public void vote(Question question, SiteUser siteUser) {
        // voter 에 user 를 추가
        // voter 는 중복을 막기위해 타입이 Set 으로 구현 되어있다.
        question.getVoter().add(siteUser);

        questionRepository.save(question);
    }

✏️ Controller 계층 - 좋아요 추가 기능

@Controller
@RequestMapping("/question")
@RequiredArgsConstructor
public class QuestionController {

    private final QuestionService questionService;
    private final UserService userService;

    //-- 좋아요 추가기능 --//
    @GetMapping("vote/{id}")
    @PreAuthorize("isAuthenticated()")
    public String questionVote(
            @PathVariable Integer id,
            Principal principal
    ) {
        Question question = questionService.getQuestion(id);
        SiteUser user = userService.getUser(principal.getName());

        questionService.vote(question, user);
        return "redirect:/question/detail/" + id;
    }
profile
잘못된 내용 PR 환영
post-custom-banner

0개의 댓글