メインコンテンツにスキップ

model: モデルにカスタムメソッドを追加する

info

Prisma Client エクステンションはバージョン 4.16.0 以降で一般提供されています。これらはバージョン 4.7.0 でプレビュー導入されました。4.16.0 より前のバージョンを実行している場合は、clientExtensionsプレビュー機能フラグを必ず有効にしてください。

model Prisma Client エクステンションコンポーネントタイプを使用すると、モデルにカスタムメソッドを追加できます。

modelコンポーネントの考えられる用途には、以下が含まれます。

  • findManyなど、既存のPrisma Client操作と並行して動作する新しい操作
  • カプセル化されたビジネスロジック
  • 反復的な操作
  • モデル固有のユーティリティ

カスタムメソッドを追加する

$extends クライアントレベルメソッドを使用して、拡張クライアントを作成します。拡張クライアントは、1つ以上のエクステンションでラップされた標準のPrisma Clientのバリアントです。modelエクステンションコンポーネントを使用して、スキーマ内のモデルにメソッドを追加します。

特定のモデルにカスタムメソッドを追加する

スキーマ内の特定のモデルを拡張するには、次の構造を使用します。この例では、userモデルにメソッドを追加します。

const prisma = new PrismaClient().$extends({
name?: '<name>', // (optional) names the extension for error logs
model?: {
user: { ... } // in this case, we extend the `user` model
},
});

次の例では、signUpというメソッドをuserモデルに追加します。このメソッドは、指定されたメールアドレスで新しいユーザーを作成します。

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

アプリケーションでsignUpを次のように呼び出します。

const user = await prisma.user.signUp('john@prisma.io')

スキーマ内のすべてのモデルにカスタムメソッドを追加する

スキーマ内のすべてのモデルを拡張するには、次の構造を使用します。

const prisma = new PrismaClient().$extends({
name?: '<name>', // `name` is an optional field that you can use to name the extension for error logs
model?: {
$allModels: { ... }
},
})

次の例では、existsメソッドをすべてのモデルに追加します。

const prisma = new PrismaClient().$extends({
model: {
$allModels: {
async exists<T>(
this: T,
where: Prisma.Args<T, 'findFirst'>['where']
): Promise<boolean> {
// Get the current model at runtime
const context = Prisma.getExtensionContext(this)

const result = await (context as any).findFirst({ where })
return result !== null
},
},
},
})

アプリケーションでexistsを次のように呼び出します。

// `exists` method available on all models
await prisma.user.exists({ name: 'Alice' })
await prisma.post.exists({
OR: [{ title: { contains: 'Prisma' } }, { content: { contains: 'Prisma' } }],
})

別のカスタムメソッドからカスタムメソッドを呼び出す

2つのメソッドが同じモデルで宣言されている場合、別のカスタムメソッドからカスタムメソッドを呼び出すことができます。たとえば、userモデルのカスタムメソッドを、別のuserモデルのカスタムメソッドから呼び出すことができます。2つのメソッドが同じエクステンションで宣言されているか、異なるエクステンションで宣言されているかは関係ありません。

これを行うには、Prisma.getExtensionContext(this).methodNameを使用します。prisma.user.methodNameは使用できないことに注意してください。これは、prismaがまだ拡張されておらず、新しいメソッドが含まれていないためです。

例:

const prisma = new PrismaClient().$extends({
model: {
user: {
firstMethod() {
...
},
secondMethod() {
Prisma.getExtensionContext(this).firstMethod()
}
}
}
})

実行時に現在のモデル名を取得する

info

この機能はバージョン 4.9.0 以降で使用可能です。

Prisma.getExtensionContext(this).$nameを使用して、実行時に現在のモデルの名前を取得できます。これを使用して、モデル名をログに出力したり、名前を別のサービスに送信したり、モデルに基づいてコードを分岐したりできます。

例:

// `context` refers to the current model
const context = Prisma.getExtensionContext(this)

// `context.name` returns the name of the current model
console.log(context.name)

// Usage
await(context as any).findFirst({ args })

実行時に現在のモデル名を取得する具体的な例については、スキーマ内のすべてのモデルにカスタムメソッドを追加するを参照してください。

高度な型安全: ジェネリックエクステンションを定義するための型ユーティリティ

型ユーティリティを使用すると、共有エクステンションのmodelコンポーネントの型安全性を向上させることができます。