Models
먼저 동네생활을 위한 데이터 베이스 스키마를 만들어 주겠습니다.
먼저 Community(동네 생활)에서의 형태는 다음과 같습니다. 이를 하나의 Post라고 하겠습니다. 이 Post의 작성자가 있을 것이고, 이에 대한 답변이 있을 겁니다. 그리고 질문이 있을것이고, 같이 궁금해 하는 사람이 있을 겁니다.
이를 위해서 스키마를 변경해 보도록 하겠습니다.
/schema.prisma
model User {
id Int @id @default(autoincrement())
phone String? @unique
email String? @unique
name String
avatar String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tokens Token[]
products Product[]
fav Fav[]
Post Post[]
answers Answer[]
wondering Wondering[]
}
...
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
question String @db.MediumText
answers Answer[]
wondering Wondering[]
}
model Answer {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
postId Int
answer String @db.MediumText
}
model Wondering {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
postId Int
}
우선 Answer를 만들어 주고, Post와 User에 Answer를 1:n 매핑 시켜 줍니다. 그리고 Wondering 모델도 만들고 Post와 User에 Wondering도 1:n매핑 시켜줍니다.
그 다음에는 이제 Community탭에서 글을 작성하는 /community/write엔드포인트를 완성시켜보도록 하겠습니다. 이를 하기 위해서는 먼저 TextArea에 구현되지 않은 react-hook-form을 완성시켜 주어야 합니다. 그리고 api router에 /api/posts/index.ts하나 만들고 글을 등록하는 api를 하나 만들었습니다.
/pages/community/write.tsx
import type { NextPage } from "next";
import Layout from "@components/layout";
import Button from "@components/button";
import TextArea from "@components/textArea";
import { useForm } from "react-hook-form";
import useMutation from "@libs/client/useMutation";
import { useEffect } from "react";
import { Post } from "@prisma/client";
import { useRouter } from "next/router";
interface WriteForm {
question: string;
}
interface WriteResponse {
ok: boolean;
post: Post;
}
const Write: NextPage = () => {
const router = useRouter();
const { register, handleSubmit } = useForm<WriteForm>();
const [post, { loading, data }] =
useMutation<WriteResponse>("/api/posts");
const onValid = (data: WriteForm) => {
if (loading) return;
post(data);
};
useEffect(() => {
if (data && data.ok) {
router.push(`/community/${data.post.id}`);
}
}, [data, router]);
return (
<Layout canGoBack>
<form
onSubmit={handleSubmit(onValid)}
className="space-y-2 px-4"
>
<div className="px-4">
<TextArea
register={register("question", {
required: true,
minLength: 5,
})}
placeholder="Ask a question!"
required
/>
<Button text={loading ? "Loading..." : "submit"} />
</div>
</form>
</Layout>
);
};
export default Write;
/api/posts/index.ts
import client from "@libs/client/client";
import withHandler, {
ResponseType,
} from "@libs/server/withHandler";
// prettier-ignore
import type { NextApiRequest, NextApiResponse, NextApiHandler } from "next";
import { withApiSession } from "@libs/server/withSession";
const handler: NextApiHandler = async (
req: NextApiRequest,
res: NextApiResponse
) => {
const {
body: { question },
session: { user },
} = req;
const post = await client.post.create({
data: {
question,
user: {
connect: {
id: user?.id,
},
},
},
});
res.json({
ok: true,
post,
});
};
export default withApiSession(
withHandler({
methods: ["POST"],
handler,
})
);
이 코드를 완성 시키고, 글을 하나 등록 시켜보도록 하겠습니다.
바로 해당하는 post의 id로 redirection이 되는 것을 보실 수 있습니다. 정상적으로 prisma studio에서 글이 등록되었는지 확인해 보겠습니다.
post id가 1인 글이 등록 되었고 /community/1로 리다이렉션 된 것보니 정상 작동하는 확인할 수 있었습니다.
'Web > CloneCoding' 카테고리의 다른 글
[Carrot Market] #11 - PRODUCT - FINISH (0) | 2022.05.18 |
---|---|
[Carrot Market] #11 PRODUCTS - START (0) | 2022.05.17 |
[Carrot Market] #10 - AUTHORIZATION (0) | 2022.05.13 |
[Carrot Market] #9 - Authentication - 2 (0) | 2022.05.12 |
[Carrot Market] #9 - Authentication - 1 (0) | 2022.05.12 |