[TIL] 뉴스피트 프로젝트 02

최하온·2024년 2월 15일
0

TIL

목록 보기
34/71
post-thumbnail

API

좋아요

🚨Issue occuring


Likes 테이블의 post_Id의 갯수를 기준으로 좋아요 카운팅해야겠다고 생각하여 코드를 짜주었다.


prisma.likes.create({}) 부분에서 prisma와 관련해 Likes_user_Id_key에 관련된 오류 발생

💦What I tried


await prisma.likes.create({
        data: {
          user_Id: +user_Id,
          post_Id: +post_Id,
        },
      });
model Likes {
 id      Int   @id @default(autoincrement()) @db.UnsignedInt
 user_Id Int   @unique @db.UnsignedInt
 post_Id Int   @unique @db.UnsignedInt
 post    Posts @relation(fields: [post_Id], references: [id], onDelete: Cascade)
 user    Users @relation(fields: [user_Id], references: [id], onDelete: Cascade)
}

create문에는 문제가 없어보였고 프리즈마에 제약 조건이 이상한 거 같아 코드를 살펴보자.

요구조건은 한 명의 유저하나의 게시글에만 좋아요를 누를 수 있어야 한다.
각자 unique 제약 조건을 걸어주는게 문제였다.
기존 모델은
전체글중 하나의 게시글만 좋아요를 받을 수 있고, 모든 유저는 전체 게시글 중 하나만 좋아요를 누를 수 있다.🤨
무언가 이상하다. 내가 원하는 요구 조건에 맞추려면 user && post !== null이어여한다.
어떻게 하면 두 개를 하나의 unique로 할 수 있을까.

💡How solve issue


model Likes {
  id      Int   @id @default(autoincrement()) @db.UnsignedInt
  user_Id Int   @db.UnsignedInt
  post_Id Int   @db.UnsignedInt
  post    Posts @relation(fields: [post_Id], references: [id], onDelete: Cascade)
  user    Users @relation(fields: [user_Id], references: [id], onDelete: Cascade)

  @@unique([user_Id, post_Id])
}

각자 unique였던 user_Id, post_Id의 제약 조건을 unique 그룹으로 걸어주었다.

router.post('/posts/:id/like', authMiddleware, async (req, res) => {
  try {
    	// 코드
    const existingLike = await prisma.likes.findFirst({
      where: {
        user_Id: +user_Id,
        post_Id: +post_Id,
      },
    });
    	// 코드
    if (!existingLike) {
      await prisma.likes.create({
        data: {
          user_Id: +user_Id,
          post_Id: +post_Id,
        },
      });
    } else {
      return res.status(400).json({ message: '이미 좋아요를 눌렀습니다.' });
    }
		// 코드

});

likes 테이블에서 id들을 가져 온 뒤, existingLike에 할당해주고 existingLike'가 없는 경우에만 새로운 좋아요를 생성.
테이블에 이미 레코드가 있다면 좋아요를 눌렀다고 반환.

좋아요 취소

    if (existingLike) {
      const id = existingLike.id;
      await prisma.likes.delete({
        where: { id: +id },
      });

좋아요 기능과 로직이 비슷하다. 삭제할 Like의 id를 가져와 delete 해주었다.

좋아요 TOP10

🚨Issue occuring


도저히 포스트 조회에 좋아요 테이블의 post_Id를 카운팅할 방법이 생각이 나지 않았다.

💦What I tried


Likes테이블을 조회하여 Id를 가져와보기, post_Id만 가져와보기 등 여러 방법을 써보았지만 모르겠음.
prisma 공식 문서에서 _count를 발견하여 사용해보았지만 실패.
차근차근 접근해보자.
1. Likes 필드에 접근하기(중첩 select문 사용)
2. 좋아요 정보 가져오기 (id)
3. 카운트하기 (_count)
4. 내림차순으로 정렬(orderby, desc)

💡How solve issue


router.get('/posts/likes/top10', async (req, res) => {
  try {
    const topLikedPosts = await prisma.posts.findMany({
      	// 코드
        likes: {
          select: {
            id: true,
          },
        },
      },
      orderBy: {
        likes: {
          _count: 'desc',
        },
      },
      take: 10,
    });

    const formattedTopLikedPosts = topLikedPosts.map((post) => ({
		// 코드
      likeCount: post.likes.length, // 좋아요 수를 배열 길이로 가져옴
    }));

		// 코드
});

likes 필드에서 id를 기준으로 게시물에 대한 좋아요의 정보를 가져온 뒤,
orderBy절을 사용하여 좋아요를 내림차순으로 정렬하여 10개의 결과만 조회하였다.
map사용으로 새로운 배열을 만들어 준 뒤 배열의 길이를 넣어주었다. => 숫자로 나옴

📃What I learned new


전체적으로 prisma에 사용법에 많이 익숙해진 거 같다.

0개의 댓글