跳到主要内容

自定义模型

随着你的应用程序增长,你可能会发现需要将相关的逻辑组合在一起。我们建议以下两种方式之一

  • 使用 Prisma Client 扩展创建静态方法
  • 将模型包装在一个类中
  • 扩展 Prisma Client 模型对象

使用 Prisma Client 扩展的静态方法

以下示例演示了如何创建一个 Prisma Client 扩展,该扩展向 User 模型添加了 signUpfindManyByDomain 方法。

import bcrypt from 'bcryptjs'
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient().$extends({
model: {
user: {
async signUp(email: string, password: string) {
const hash = await bcrypt.hash(password, 10)
return prisma.user.create({
data: {
email,
password: {
create: {
hash,
},
},
},
})
},

async findManyByDomain(domain: string) {
return prisma.user.findMany({
where: { email: { endsWith: `@${domain}` } },
})
},
},
},
})

async function main() {
// Example usage
await prisma.user.signUp('[email protected]', 's3cret')

await prisma.user.findManyByDomain('example2.com')
}

将模型包装在一个类中

在下面的示例中,你将看到如何将 Prisma Client 中的 user 模型包装在 Users 类中。

import { PrismaClient, User } from '@prisma/client'

type Signup = {
email: string
firstName: string
lastName: string
}

class Users {
constructor(private readonly prismaUser: PrismaClient['user']) {}

// Signup a new user
async signup(data: Signup): Promise<User> {
// do some custom validation...
return this.prismaUser.create({ data })
}
}

async function main() {
const prisma = new PrismaClient()
const users = new Users(prisma.user)
const user = await users.signup({
email: '[email protected]',
firstName: 'Alice',
lastName: 'Prisma',
})
}

有了这个新的 Users 类,你可以定义自定义函数,例如 signup

请注意,在上面的示例中,你仅从 Prisma Client 公开了一个 signup 方法。Prisma Client 隐藏在 Users 类中,因此你将无法再调用诸如 findManyupsert 之类的方法。

当你的应用程序很大,并且你想要有意限制你的模型可以做什么时,这种方法效果很好。

扩展 Prisma Client 模型对象

但是,如果你不想隐藏现有功能,但仍然想将自定义函数组合在一起怎么办?在这种情况下,你可以使用 Object.assign 来扩展 Prisma Client,而不会限制其功能

import { PrismaClient, User } from '@prisma/client'

type Signup = {
email: string
firstName: string
lastName: string
}

function Users(prismaUser: PrismaClient['user']) {
return Object.assign(prismaUser, {
/**
* Signup the first user and create a new team of one. Return the User with
* a full name and without a password
*/
async signup(data: Signup): Promise<User> {
return prismaUser.create({ data })
},
})
}

async function main() {
const prisma = new PrismaClient()
const users = Users(prisma.user)
const user = await users.signup({
email: '[email protected]',
firstName: 'Alice',
lastName: 'Prisma',
})
const numUsers = await users.count()
console.log(user, numUsers)
}

现在,你可以将你的自定义 signup 方法与 countupdateManygroupBy() 以及 Prisma Client 提供的所有其他出色方法一起使用。最棒的是,这一切都是类型安全的!

深入了解

我们建议使用 Prisma Client 扩展来使用自定义模型方法扩展你的模型。