自訂模型
隨著應用程式的成長,您可能會發現需要將相關邏輯組合在一起。我們建議以下任一方式
- 使用 Prisma Client 擴充功能建立靜態方法
- 將模型包裝在類別中
- 擴充 Prisma Client 模型物件
使用 Prisma Client 擴充功能的靜態方法
以下範例示範如何建立 Prisma Client 擴充功能,將 signUp
和 findManyByDomain
方法新增至 User 模型。
- Prisma Client 擴充功能
- Prisma schema
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('user2@example2.com', '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 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: 'alice@prisma.io',
firstName: 'Alice',
lastName: 'Prisma',
})
}
有了這個新的 Users
類別,您可以定義自訂函數,例如 signup
請注意,在上述範例中,您僅公開 Prisma Client 的 signup
方法。Prisma Client 隱藏在 Users
類別中,因此您將無法再呼叫 findMany
和 upsert
等方法。
當您有大型應用程式且想要刻意限制模型的功能時,此方法效果良好。
擴充 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: 'alice@prisma.io',
firstName: 'Alice',
lastName: 'Prisma',
})
const numUsers = await users.count()
console.log(user, numUsers)
}
現在,您可以將您的自訂 signup
方法與 count
、updateMany
、groupBy()
以及 Prisma Client 提供的所有其他出色方法一起使用。最棒的是,這一切都是型別安全的!
進一步了解
我們建議使用 Prisma Client 擴充功能,透過自訂模型方法來擴充您的模型。