多対多リレーションの作成と編集: Prismaのconnectとsetの使い分け
開発環境
- next 14.2.13
- prisma 5.19.1
- @prisma/client 5.19.1
前提
Prismaは、ORMとして効率的にデータベース操作を行うための強力なツールです。多対多のリレーションを扱うとき、レコードの作成や編集においてconnectとsetの使い分けが非常に重要です。このブログでは、具体的なシナリオを通してその使い方を解説します。
本題
Prismaの多対多リレーションの概要
多対多リレーションでは、2つのテーブルが「中間テーブル」を介してお互いに関連付けられます。Prismaでは、リレーションの作成や編集をconnectやsetを使って簡単に操作できます。例として、以下の2つのモデルを考えてみましょう。
model Post {
id Int @id @default(autoincrement())
title String
content String
tags Tag[]
}
model Tag {
id Int @id @default(autoincrement())
name String
posts Post[]
}
この場合、PostとTagは多対多リレーションです。Postは複数のTagを持つことができ、Tagも複数のPostに関連付けられます。
connectの使い方
connectは、既存のリレーションに新しいエントリを追加する場合に使用されます。例えば、既に存在するタグを投稿に関連付けたいときに便利です。
例: 投稿に既存のタグを追加する
const updatedPost = await prisma.post.update({
where: { id: 1 },
data: {
tags: {
connect: [{ id: 2 }, { id: 3 }],
},
},
});
この例では、id: 1の投稿にid: 2とid: 3のタグを追加しています。connectは、既存のリレーションをそのまま維持しつつ、新たなリレーションを追加する場合に最適です。
setの使い方
一方、setは、リレーションをリセットして新しいエントリに置き換える場合に使用されます。つまり、現在のリレーションをすべて解除し、新たに指定されたリレーションだけを保持します。
例: 投稿のタグを置き換える
const updatedPost = await prisma.post.update({
where: { id: 1 },
data: {
tags: {
set: [{ id: 4 }, { id: 5 }],
},
},
});
この例では、id: 1の投稿にid: 4とid: 5のタグを設定していますが、元々関連していたすべてのタグ(id: 2やid: 3)は解除され、id: 4とid: 5だけが残ります。
使い分けのポイント
- connectは、既存のリレーションをそのままにして新しいリレーションを追加したいときに使います。既存のデータを損なわずに新しい関連付けを追加できるため、安全です。また、新規作成時にもよく利用されます。
- setは、リレーションを一度クリアして、新しいリレーションだけを持つようにしたいときに使います。リレーションの状態を完全にリセットする必要がある場面で使用します。編集画面の処理ではこちらがよく利用されるでしょう。
disconnectとの違い
connectやsetに加えて、disconnectもリレーション操作において重要です。disconnectは、特定のリレーションを解除するために使用されますが、リレーションを完全にリセットするわけではありません。
例: 特定のタグを投稿から削除する
const updatedPost = await prisma.post.update({
where: { id: 1 },
data: {
tags: {
disconnect: [{ id: 2 }],
},
},
});
この例では、id: 2のタグを投稿から削除しています。他のタグ(id: 3など)はそのまま保持されます。
さいごに
Prismaのconnect、set、disconnectを使いこなすことで、多対多リレーションのレコードを効率的に作成・編集できます。connectでリレーションを追加し、setでリレーションを置き換え、disconnectで特定のリレーションを解除することができます。
これらの操作を理解することで、複雑なデータ構造を扱う際の柔軟性が向上します。ぜひ、あなたのプロジェクトで適切に使い分けてみてください!