はじめに
前回の記事でSupabaseのテーブル同士のリレーションを設定しました。
今回はReact + TypeScriptでデータを読み込むところまでの記録です。
リレーションの設定方法
リレーションの種類(ざっくり解説)
まずリレーションの記事で1対1や1対多についてざっくり解説
1対多(One-to-many)
- 1つの親に対して、複数の子が紐づく
- 例:
projects
とtasks
→ 1つのプロジェクトに複数のタスクがある
Project A ─┬─ Task 1
├─ Task 2
└─ Task 3
1対1(One-to-One)
- 1つの親に対して、子も1つだけ
- 例:
users
とuser_profiles
→ 1人のユーザーに1つのプロフィールがある
User A ── Profile A
User B ── Profile B
データとしては配列で返ってくる可能性が高い
扱う時は配列の1番目として使う のが良さそう
やりたいこと
Todoアプリのような構成で、以下のようなリレーションを作成しました
-
projects
テーブル(プロジェクト) -
tasks
テーブル(タスク) - 1つの project に複数の task が紐づく(1対多)
データを取得(React + TypeScript)
Supabaseからデータを読み込んで、コンソールに表示するサンプル
1対多のリレーション
export const getProject = async (): Promise<Projects[] | null> => {
const { data, error } = await supabase
.from("projects")
.select("id,name,tasks(id,title,is_done)");
if (error) {
console.error("Error:", error.message);
return null;
}
return data;
};
レスポンス例
[
{
"id": "1",
"name": "Project A",
"tasks": [
{
"id": "a1",
"title": "Task 1",
"is_done": false
},
{
"id": "a2",
"title": "Task 2",
"is_done": true
}
]
},
{
"id": "2",
"name": "Project B",
"tasks": [
{
"id": "b1",
"title": "Task 3",
"is_done": false
}
]
}
]
クラスの型定義
Tasks
とProject
を分けて作成し、
Projectsの中 にpublic tasks: Tasks[] = []
として設定できる
export class Tasks {
constructor(
public id: number,
public title: string,
public is_done: boolean
) {}
}
export class Projects {
constructor(
public id: number,
public name: string,
public tasks: Tasks[] = []
) {}
}
まとめと感想
Supabaseでリレーションを追加しておくことで、データ取得のコードを1つにまとめることができかなりスッキリしました。
他にもINNER JOIN や LEFT JOIN といったものがあるみたいなので、もっと学んで挑戦してみようと思いました!
参考記事
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼