먼저 좋아요 모델을 만들어야 한다.
필자는 다음과 같은 모델을 만들었다.
model Fav {
id Int @id @default(autoincrement())
userId Int
productId Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
}
좋아요 기능은 유저가 좋아요를 눌렸을 때 만약 좋아요를 누르지 않았으면 create하고 아니면 삭제하면 된다.
// client = new PrismaClient();
// 생략...
const {
query:{ id }
session: { user },
} = req;
const alreadyExists = await client.fav.findFirst({
where: {
productId: +id.toString();
userId: user?.id,
},
});
if(alreadyExists){
// 해당 아이디가 있다면 delete
await client.fav.delete({
where: {
id: alreadyExists.id
}
})
} else {
// 해당 아이디가 없다면 create
await client.fav.create({
data: {
user: {
connect: {
id: user?.id,
},
},
product: {
connect: {
id: +id.toString(),
},
},
},
});
}
res.json({ ok: true });
// 생략...
이제 해야 하는 것은 백엔드의 응답이 있기까지 기다리지 않고 변경사항을 반영해야하기 때문이다.
좋아요를 누르고 백엔드의 응답이 오기전에 미리 변경사항을 보여준다는 뜻이다.
이것은 SWR의 mutate를 사용해 구현할 것이다.
// 생략...
// 좋아요 버튼을 클릭했을 때
const onFavClick = () => {
mutate({ ...data, isLiked: !data.isLiked }, false);
}
다음과 같이 표현할 수도 있다.
mutate((prev: any) => prev && { ...prev, isLiked: !data.isLiked }, false );
다른 이야기지만 만약 로컬 데이터를 업데이트를 하고 싶다면 다음과 같이 하면 된다.
const { mutate } = useSWRConfig();
// 로컬 데이터를 업데이트, revalidation은 비활성
mutate(key값, 변경할 값); // 기본 데이터를 유지할려면 { ...data, } 처럼 작성해야 한다.
// 로컬 데이터가 올바른지 확인, revaildation 활성
mutate(key값);
이제 좋아요 개수를 확인할 수 있게 구현해보자.
Fav 모델에 favCount를 추가하는 방법도 있지만 더욱 좋은 방법이 있다.
prisma에서 제공하는 기능인 _count를 이용하는 것이다.
const products = await client.product.findMany({
include: {
_count: {
select: {
fav: true,
},
},
},
});
이러면 relation의 수(예: 사용자의 게시물 수)를 반환하기 위해서는 select과 함께 _count 매개변수를 사용한다.레코드를 반환하는 모든 쿼리와 함께 사용할 수 있다.
위와 같이 작성한다면 좋아요의 수를 쉽게 count 할 수 있다.
참고 : sugar님