1. content
在 Prisma 中,connect 是一个用于建立关系的选项,主要用于在创建或更新记录时将现有记录关联起来。connect 允许你在不重新创建相关记录的情况下,将它们链接到当前记录。这在处理多对多关系或多对一关系时特别有用。
1. connect 的作用
connect 通常用于以下几种情况:
- 创建记录时建立关系:在创建新记录时,将其与已存在的记录关联。
- 更新记录时建立关系:在更新现有记录时,将其与已存在的记录关联。
2. 一对多关系中的content
假设你有一个 User 模型和一个 Post 模型,其中 User 可以有多篇 Post。
- 模型定义
prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
age Int
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
- 创建用户并关联帖子
typescript
const user = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john.doe@example.com',
age: 25,
posts: {
connect: [{ id: 1 }, { id: 2 }], // 关联已存在的帖子
},
},
});
console.log(user);
- 更新记录时使用 connect
假设你已经有一个用户,现在想为该用户添加新的帖子。
- 更新用户并关联帖子
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
email: "newEmail@"
posts: {
connect: [{ id: 3 }], // 关联新的帖子
},
},
});
console.log(user);
3. 多对多关系中的 connect
假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。
- 模型定义
prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
age Int
roles Role[] @relation("UserRoles")
}
model Role {
id Int @id @default(autoincrement())
name String
users User[] @relation("UserRoles")
}
- 创建用户并关联角色
typescript
const user = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john.doe@example.com',
age: 25,
roles: {
connect: [{ id: 1 }, { id: 2 }], // 关联已存在的角色
},
},
});
console.log(user);
- 更新用户并关联角色
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
connect: [{ id: 3 },{ id: 4 }], // 关联新的角色
},
},
});
console.log(user);
2. connectOrCreate
作用: 用于在创建或更新记录时,将现有记录关联起来,或者在关联记录不存在时创建它。
1. 基本概念
connectOrCreate 选项允许你在关联记录不存在时创建它,并将其与当前记录关联。它接受一个数组,每个元素都是一个对象,包含 where 和 create 两个属性:
- where:用于查找现有记录的条件。如果找到匹配的记录,则将其关联。
- create:如果 where 条件没有找到匹配的记录,则使用 create 中提供的数据创建新记录,并将其关联。
2. 示例
假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。
- 模型定义
prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
age Int
roles Role[] @relation("UserRoles")
}
model Role {
id Int @id @default(autoincrement())
name String @unique
users User[] @relation("UserRoles")
}
3. 创建用户并连接或创建角色
typescript
const user = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john.doe@example.com',
age: 25,
roles: {
connectOrCreate: [
{
where: { name: 'Admin' },
create: { name: 'Admin' },
},
{
where: { name: 'Editor' },
create: { name: 'Editor' },
},
],
},
},
});
console.log(user);
-
在这个示例中:
- 如果 Role 表中已经存在 name 为 Admin 的记录,则将其与新创建的用户关联。
- 如果 Role 表中不存在 name 为 Admin 的记录,则创建一个新的 Role 记录,并将其与新创建的用户关联。
- 同样的逻辑适用于 Editor 角色。
4. 更新用户并连接或创建角色
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
connectOrCreate: [
{
where: { name: 'Moderator' },
create: { name: 'Moderator' },
},
],
},
},
});
console.log(user);
-
在这个示例中:
- 如果 Role 表中已经存在 name 为 Moderator 的记录,则将其与用户 ID 为 1 的用户关联。
- 如果 Role 表中不存在 name 为 Moderator 的记录,则创建一个新的 Role 记录,并将其与用户 ID 为 1 的用户关联。
5. 处理唯一约束
connectOrCreate 特别适合处理具有唯一约束的字段。例如,Role 模型中的 name 字段被标记为 @unique,这意味着每个角色名称必须是唯一的。connectOrCreate 确保不会创建重复的角色记录。
6. 错误处理
如果 where 条件不唯一,connectOrCreate 会抛出错误。因此,确保 where 条件能够唯一标识记录。
- 示例:处理错误
typescript
try {
const user = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john.doe@example.com',
age: 25,
roles: {
connectOrCreate: [
{
where: { name: 'Admin' },
create: { name: 'Admin' },
},
{
where: { name: 'Admin' }, // 重复的 where 条件
create: { name: 'Admin' },
},
],
},
},
});
console.log(user);
} catch (error) {
console.error('Error:', error.message);
}
在这个示例中,由于 where 条件重复,connectOrCreate 会抛出错误。
3. disconnect
作用: 用于断开现有记录之间的关系。
1. 基本概念
disconnect 选项允许你在更新记录时断开与现有记录的关联。它接受一个数组,每个元素都是一个对象,包含用于查找要断开关联的记录的条件。
2. 示例
假设你有一个 User 模型和一个 Role 模型,其中 User 可以有多个 Role,Role 也可以属于多个 User。
- 模型定义
prisma
model User {
id Int @id @default(autoincrement())
name String
email String @unique
age Int
roles Role[] @relation("UserRoles")
}
model Role {
id Int @id @default(autoincrement())
name String @unique
users User[] @relation("UserRoles")
}
3. 断开用户与角色的关联
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
disconnect: [{ id: 2 }], // 断开与角色 ID 为 2 的关联
},
},
});
console.log(user);
在这个示例中:
- where 条件指定了要更新的用户(ID 为 1)。
- data 对象中的 roles 字段使用了 disconnect 选项,传入了一个数组,数组中的每个对象都包含一个 id 属性,用于指定要断开关联的角色。
4. 断开多个关联
你可以在 disconnect 数组中指定多个对象,以断开多个关联。
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
disconnect: [{ id: 2 }, { id: 3 }], // 断开与角色 ID 为 2 和 3 的关联
},
},
});
console.log(user);
在这个示例中:
- disconnect 数组中包含了两个对象,分别指定了要断开关联的角色 ID 为 2 和 3。
5. 使用其他条件断开关联
除了使用 id,你还可以使用其他唯一字段来断开关联。
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
disconnect: [{ name: 'Editor' }], // 断开与角色名称为 'Editor' 的关联
},
},
});
console.log(user);
在这个示例中:
- disconnect 数组中的对象使用了 name 字段来指定要断开关联的角色。
6. 断开所有关联
如果你想断开用户与所有角色的关联,可以使用 set 选项并将值设置为空数组。
typescript
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
set: [], // 断开与所有角色的关联
},
},
});
console.log(user);
在这个示例中:
- set 选项将 roles 设置为空数组,从而断开用户与所有角色的关联。
7. 错误处理
如果 disconnect 中的条件不匹配任何记录,Prisma 不会抛出错误,而是简单地忽略该条件。因此,你需要确保条件是正确的,以避免意外的行为。
typescript
try {
const user = await prisma.user.update({
where: {
id: 1,
},
data: {
roles: {
disconnect: [{ id: 999 }], // 不存在的角色 ID
},
},
});
console.log(user);
} catch (error) {
console.error('Error:', error.message);
}
在这个示例中:
- disconnect 中的 id: 999 不存在,Prisma 会忽略该条件,不会抛出错误。