今回のゴール

  • TODOを入力し、追加ボタンを押下するとDBへTODOが追加される
  • 画面で表示できる

schemaの設定

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./dev.db"
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  todos     Todo[]
  createdAt DateTime @default(now())
}

model Todo {
  id        Int      @id @default(autoincrement())
  title     String
  completed Boolean  @default(false)

  user      User     @relation(fields: [userId], references: [id])
  userId    Int

  createdAt DateTime @default(now())
}

actions.ts って

'use server';

import { prisma } from '@/lib/prisma';

export async function addTodo(formData: FormData) {
  const title = formData.get('title') as string;

  if (!title) return;

  await prisma.todo.create({
    data: {
      title,
      userId: 1, // 仮ログイン
    },
  });
}

サーバーで実行される処理をまとめておくファイル。
page.tsxから呼ばれる処理を置くため、page.tsxを並列に配置する。

  • DB の create / update / delete
  • 認証チェック
  • revalidatePath
  • トランザクション

上記コードはいったん、userId=1に紐づくTodoを1件作成する処理。

表示処理

findManyを使用して条件に合うレコードを取得する

import { prisma } from '@/lib/prisma';
import { addTodo } from './actions';

export default async function Page() {
  const todos = await prisma.todo.findMany({
    where: { userId: 1 },
  });

  return (
    <div>
      <h1 className="text-2xl font-black">Todo</h1>

      <form action={addTodo}>
        <input type='text' name='title' placeholder='やることを書く' className="border h-10"/>
        <button type='submit' className="ml-2 px-4 py-2 bg-blue-500 text-white rounded">追加</button>
      </form>

      <ul>
        {todos.map((todo: { id: number; title: string }) => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>
    </div>
  );
}

findManyは下記SQLとほぼ一緒とのこと

SELECT *
FROM Todo
WHERE userId = 1
ORDER BY createdAt DESC;

PrismaClientはシングルトンで扱う

あらゆるページでそれぞれnew clientをしてしまうと、複数の PrismaClient インスタンスが勝手に作られてしまい、DB 接続が増えすぎる可能性がある。そのため、/lib/prisma.tsでクライアントを作成し、それぞれのページから呼び出すようにする。

参考:https://www.prisma.io/docs/orm/more/help-and-troubleshooting/nextjs-help

import { PrismaClient } from '@prisma/client';

const globalForPrisma = global as unknown as {
  prisma: PrismaClient;
};

export const prisma =
  globalForPrisma.prisma ??
  new PrismaClient({
    log: ['query'], //  実行された SQL を console に出す
  });

if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma;
}

今回できたこと

  • Todoを入力して追加を押下すると、DBへ追加される
  • 追加したデータが表示される(ただし、リロード要)

c.sakyou

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA