LoginSignup
3
1

Prismaでの多対多(Many-to-Many)リレーションが便利だった

Last updated at Posted at 2023-12-22

岩手アドベントカレンダー

ちょっと今年は過疎ってますが、岩手在住のエンジニアとして参加します。

Prismaで多対多(Many-to-Many)のリレーションを行う

本来、多対多のリレーションを行うに中間テーブルの作成を行う必要があります。
ですが、Prismaでは自動で中間テーブルの作成を行ってくれます。
その他クエリの扱いも楽になるので非常に便利です。

実践

公式ドキュメントを例として記述します。

データモデルの設定

例としてPOSTとCategoryというテーブルを設定します。
それぞれのテーブルにリレーションを追加してあげます。

これでマイグレーションすると_CategoryToPost というテーブルが自動で作成されます。(_テーブルA To テーブルB)

model Post {
  id         Int        @id @default(autoincrement())
  title      String
  categories Category[] ←追加
}

model Category {
  id    Int    @id @default(autoincrement())
  name  String
  posts Post[] ←追加
}

実際のマイグレーションファイル

CREATE TABLE "_CategoryToPost" (
    "A" integer NOT NULL REFERENCES "Category"(id) ,
    "B" integer NOT NULL REFERENCES "Post"(id)
);
CREATE UNIQUE INDEX "_CategoryToPost_AB_unique" ON "_CategoryToPost"("A" int4_ops,"B" int4_ops);
CREATE INDEX "_CategoryToPost_B_index" ON "_CategoryToPost"("B" int4_ops);

CREATE TABLE "Category" (
    id integer SERIAL PRIMARY KEY
);

CREATE TABLE "Post" (
    id integer SERIAL PRIMARY KEY
)

クエリの方法

自動で生成された中間テーブルですが、どのように扱うのでしょうか?

create(connect)

connectを使用することで中間テーブルへ自動で紐づけを行ってくれます。

const newPost = await prisma.post.create({
  data: {
    title: '新しいポストのタイトル',
    categories: {
      connect: [
        { id: 1 }, // 既存のカテゴリーID
        { id: 2 }  // 別のカテゴリーID
      ]
    }
  }
});

Update

updateはsetを使うといいです。setを使用すると、関連付けられたすべての既存のレコードが新しいレコードで置き換えられます。

const newPost = await prisma.post.create({
  data: {
    title: '新しいポストのタイトル',
    categories: {
      set: [
        { id: 1 }, // 既存のカテゴリーID
        { id: 2 }  // 別のカテゴリーID
      ]
    }
  }
});

delete

postレコードの削除によって自動で削除されます。(べんり~)

connect,setってなに?

Prismaで多対多のリレーションシップを扱う際に使用する主要な機能には、connect、disconnect、setなどがあります。これらの機能は、関連するレコード間のリンクを管理するために使用されます。

  • connect: 追加する場合
  • disconnect: 一部を削除する
  • set: 新しいレコードへ置き換える
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1