概要
Prismaを用いてリレーション先の情報を一緒に取得して表示に使う方法を簡単にまとめる。
前提
下記の内容が完了していること
現状の確認
task category master idは
- 1: Work
- 2: Study
- 3: Other
のようにIDと内容がリンクしている。
しかしながら今はこのIDを直接画面に表示してしまっているのでパッと見でなんのカテゴリーのタスクであるかわかりにくい。
これをtasksテーブルでtask_category_mastersテーブルのidを持っているのでリレーション先のnameを使ってわかりやすく表示したい。
方法
-
app/routes/tasks-loader.tsを下記のように修正し、リレーション先の情報も取得できるように実装
app/routes/tasks-loader.tsimport type { LoaderFunctionArgs } from "@remix-run/cloudflare"; export const loader = async ({ context, request }: LoaderFunctionArgs) => { const url = new URL(request.url); const searchParams = url.searchParams; const isCompleteParam: unknown = searchParams.get("isComplete"); const isComplete: boolean = isCompleteParam === "true" ? true : false; const isDeletedParam: unknown = searchParams.get("isDeleted"); const isDeleted: boolean = isDeletedParam === "true" ? true : false; const taskCategoryMasterIdParams: string[] = searchParams.getAll("taskCategoryMasterId"); const taskCategoryMasterIds: number[] = taskCategoryMasterIdParams.map(id => Number(id)); const isTrue = 1; // フラグONの意味 マジックナンバー申し訳ない。。 try { const tasks = await context.db.tasks.findMany({ where: { ...(isComplete && { is_complete: isTrue }), ...(isDeleted && { deleted_at: {not: null}}), ...(taskCategoryMasterIds.length > 0 && { task_category_master_id: { in: taskCategoryMasterIds } }), }, include: { task_category_master: true, // schema.prismaで定義したリレーションを指定 }, }); return tasks; } catch (error) { console.error("Failed to load tasks:", error); throw new Response("Internal Server Error", { status: 500 }); } }
-
app/routes/tasks.tsxを下記のように修正し、型情報の追加とカテゴリ情報の表示データのソースを変更
app/routes/tasks.tsximport type { MetaFunction } from "@remix-run/cloudflare"; import { loader } from "./tasks-loader"; export { loader }; import { useLoaderData } from "@remix-run/react"; export const meta: MetaFunction = () => { return [ { title: "tasks" }, { name: "description", content: "tasks", }, ]; }; interface Task { id: string; name: string; memo: string; is_complete: boolean; task_category_master_id: string; created_at: string; updated_at: string; task_category_master: { id: string; name: string; }; } export default function Index() { const tasks = useLoaderData<Task[]>(); return ( <div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}> <h1>tasks</h1> <ul> {tasks.map((task: Task) => ( <li key={task.id}> <div>id: {task.id}</div> <div>name: {task.name}</div> <div>memo: {task.memo}</div> <div>is complete: {task.is_complete}</div> <div>task category: {task.task_category_master.id}</div> <div>created at: {task.created_at}</div> <div>updated at: {task.updated_at}</div> </li> ))} </ul> </div> ); }
-
下記のように一覧表示でidではなくカテゴリ名で表示されていれば完了