自定义模型
随着应用程序的增长,您可能会发现需要将相关的逻辑分组在一起。我们建议以下两种方式:
- 使用 Prisma 客户端扩展 创建静态方法
- 将模型包装在类中
- 扩展 Prisma 客户端模型对象
使用 Prisma 客户端扩展的静态方法
以下示例演示了如何创建一个 Prisma 客户端扩展,它为 User 模型添加了 signUp
和 findManyByDomain
方法。
- Prisma 客户端扩展
- Prisma 模式
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/schema.prisma"
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
email String
password Password?
}
model Password {
hash String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
userId String @unique
}
将模型包装在类中
在下面的示例中,您将看到如何将 Prisma 客户端中的 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 客户端公开了 signup
方法。Prisma 客户端隐藏在 Users
类中,因此您将无法再调用诸如 findMany
和 upsert
之类的方法。
当您拥有大型应用程序并且希望有意限制模型的功能时,这种方法非常有效。
扩展 Prisma 客户端模型对象
但是,如果您不想隐藏现有功能,但仍然希望将自定义函数分组在一起怎么办?在这种情况下,您可以使用 Object.assign
来扩展 Prisma 客户端,而不会限制其功能
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
方法以及 count
、updateMany
、groupBy()
和 Prisma 客户端提供的所有其他出色方法。最棒的是,它是类型安全的!
更进一步
我们建议使用 Prisma 客户端扩展 来使用 自定义模型方法 扩展您的模型。