Likes 테이블의 post_Id의 갯수를 기준으로 좋아요 카운팅해야겠다고 생각하여 코드를 짜주었다.
prisma.likes.create({}) 부분에서 prisma와 관련해 Likes_user_Id_key에 관련된 오류 발생
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로 할 수 있을까.
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 해주었다.
도저히 포스트 조회에 좋아요 테이블의 post_Id를 카운팅할 방법이 생각이 나지 않았다.
Likes테이블을 조회하여 Id를 가져와보기, post_Id만 가져와보기 등 여러 방법을 써보았지만 모르겠음.
prisma 공식 문서에서 _count를 발견하여 사용해보았지만 실패.
차근차근 접근해보자.
1. Likes 필드에 접근하기(중첩 select문 사용)
2. 좋아요 정보 가져오기 (id)
3. 카운트하기 (_count)
4. 내림차순으로 정렬(orderby, desc)
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사용으로 새로운 배열을 만들어 준 뒤 배열의 길이를 넣어주었다. => 숫자로 나옴
전체적으로 prisma에 사용법에 많이 익숙해진 거 같다.