Open5
Next.js、prisma、supabaseでユーザー投稿
Prismaの導入
prismaと@prisma/clientをインストール
npm install prisma --save-dev
npm install @prisma/client
ファイルを作成し、以下を記述
src/lib/prisma.ts
import { PrismaClient } from "@prisma/client";
const prismaClientSingleton = () => {
return new PrismaClient();
};
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
export default prisma;
if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;
Prismaの初期化
以下のコマンドを実行しPrismaの初期化をする
npx prisma init
初期化すると prisma/schema.prisma
と .env
ファイルが作られる。
既存の.env
が存在していれば、それにDATABASE_URLの環境変数が追加される
DATABASE_URLはsupabaseのURLに変更する必要がある。
ヘッダー部分にある「Connect」をクリックするとモーダルが開く。
その中の「ORMs」タブを開きPrismaを選択 .env.local
を .env
ファイルに追記。
[YOUR-PASSWORD]
の部分は最初に設定したDBパスワードを指定
prisma/schema.prisma
もタブに書かれているない様に変更( directUrl = env("DIRECT_URL")
を追記)
migrate
prisma/schema.prisma
に以下を追加。
公式ドキュメント参照
ドキュメントのidはintだが、UUIDを使う様にしたためstringに
model User {
id String @id
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
}
以下を実行すると prisma/migrations
が生成される
npx prisma migrate dev --name init
管理画面のTable Editorでは定義したDBのテーブルが追加されている
POST
以下のようなpostする処理を書く。
適当にフォームや送信ボタンを作って送信するとDBに保存される
const createPost = async (formData: FormData) => {
"use server";
const title = formData.get("title") as string;
const content = formData.get("content") as string;
if (!title) return;
const supabaseServer = await createClient();
const { data: { user: currentUser } } = await supabaseServer.auth.getUser();
if (!currentUser?.id) return;
let dbUser = await prisma.user.findUnique({
where: { id: currentUser.id }
});
if (!dbUser) {
dbUser = await prisma.user.create({
data: {
id: currentUser.id,
email: currentUser.email || "",
name: currentUser.user_metadata?.full_name || null
}
});
}
await prisma.post.create({
data: {
title,
content,
authorId: currentUser.id
}
});
revalidatePath("/dashboard");
};
一覧を取得
以下を書くとuserPosts
に投稿データが格納されるので、mapすると一覧が表示される
// ログインユーザーの投稿を取得
let userPosts: any[] = [];
if (user?.id) {
userPosts = await prisma.post.findMany({
where: {
authorId: user.id
},
orderBy: {
createdAt: 'desc'
},
include: {
author: {
select: {
name: true,
email: true
}
}
}
});
}