11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PrismaのManytoManyのデータ紐付け方法で苦戦したのでメモ

Last updated at Posted at 2022-09-29

Schema

スキーマ自体はPrismaのドキュメントを見ながら作成
暗黙的と明示的な連携があるようだが、今回は明示的な連携を選択

model User {
  id        String  @id @default(cuid())
  name      String?
  email     String
  projects  ProjectsOnUsers[]
  createdAt DateTime  @default(now())
  updatetAt DateTime  @updatedAt
}

model Project {
  id        Int  @id @default(autoincrement())
  name      String
  users     ProjectsOnUsers[]
}

model ProjectsOnUsers {
  user        User    @relation(fields: [userId], references: [id])
  userId      String
  project     Project @relation(fields: [projectId], references: [id])
  projectId   Int
  assignedAt  DateTime  @default(now())
  assignedBy  String
  @@id([userId, projectId])
}

UserとProjectを一括で作成

サンプルのQueryで記載されているのもこのパターン
これはそのままなので比較的簡単にできる。

await prisma.user.create({ // UserのCreate
    data: {
      name: 'username', // CreateするUserの情報
      email: 'test@example.com', // CreateするUserの情報
      projects: {
        create: { // Relationテーブルを作成するのでCreate
          project: { 
            create: { // 紐付けるProjectをCreate
              name: 'sand Project', // CreateするProjectの情報
            },
          },
          assignedBy: 'takaho', // CreateするRelationの情報
        },
      },
    },
})

既に作成済みのUserに対して作成済みのProjectを紐付け

こちらがだいぶ苦戦したが、通るクエリがかけたタイミングでようやく理解
create部分が配列にしているがここは単体でも特に問題なく動く

await prisma.user.update({
    where: { id: 'fuga' }, // Update対象ユーザー
    data: {
      projects: { // Relationを追加するのでUpdate対象
        create: [ // Relationを新規追加するのでcreate
          {
            project: {
              connect: { id: 1 }, // 既存Projectを紐づけるのでconnect
            },
            assignedBy: 'hage', // Relationの情報
          },
        ],
      },
    },
  })

Userに紐づいたProjectのRelation解除

await prisma.user.update({
    where: { id: 'cl8n7bioo0073zz1i9ozq2xhs' },
    data: {
      projects: {
        delete: {
          userId_projectId: {
            projectId: 10,
            userId: 'cl8n7bioo0073zz1i9ozq2xhs',
          },
        },
      },
    },
  })

既存Userに新規作成Projectを紐付け

await prisma.user.update({

    where: { id: 'hogehoge' },
    data: {
      projects: {
        create: {
          project: {
            create: {
              name: 'New',
            },
          },
          assignedBy: 'hage',
        },
      },
    },
  })

まとめ

この辺りを意識するとそこまで沼にハマらずに済むかも。

  • どのレコードを作成するのかの意識
  • 対象のレコードは既にあるのか作るのか
  • テーブルの必須項目が抜けていないか
  • 結構不整合データが発生できてしまう
  • その場合にはWebUI上からも削除不可
  • 何かしらのゴミリレーションが邪魔しているのでそれを消す
11
3
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
11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?