NestJS中class-validator自定义唯一校验无法注入MongoDB模型如何解决
你遇到的报错是因为默认情况下class-validator创建的自定义校验器实例不由NestJS的依赖注入容器托管,因此@InjectModel注解无法正常注入Mongoose模型,导致userModel为undefined。
步骤1:给自定义校验器添加@Injectable装饰器
给你的UniqueValidator类加上@Injectable()装饰器,标记它可被Nest的IoC容器管理:
import { Injectable } from "@nestjs/common"; // 新增导入 import { getModelToken, InjectModel } from "@nestjs/mongoose"; import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface, } from "class-validator"; import { Model } from "mongoose"; import { User } from "../schema/user.schema"; @Injectable() // 新增装饰器 @ValidatorConstraint({ name: "IsUniqueUser", async: true }) export class UniqueValidator implements ValidatorConstraintInterface { constructor( @InjectModel(User.name) private readonly userModel: Model<User>, ) {} async validate(value: any, args: ValidationArguments) { const filter = {}; filter[args.property] = value; // 注意:mongoose旧版count方法已废弃,建议替换为countDocuments const count = await this.userModel.countDocuments(filter); return !count; } defaultMessage(args: ValidationArguments) { return "$(value) is already taken"; } }
步骤2:将校验器注册为模块提供者
在你引入了User模型的模块(比如UserModule)的providers数组中注册UniqueValidator,让Nest可以完成依赖注入的实例化:
import { Module } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { User, UserSchema } from './schema/user.schema'; import { UniqueValidator } from './validator/unique.validator'; @Module({ imports: [ MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]) ], providers: [UniqueValidator], // 注册校验器为提供者 exports: [UniqueValidator] // 如果其他模块需要使用这个校验器,加导出 }) export class UserModule {}
步骤3:配置class-validator使用Nest容器
在项目启动文件main.ts中添加配置,让class-validator使用Nest的依赖容器创建校验器实例:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { useContainer } from 'class-validator'; // 导入配置方法 async function bootstrap() { const app = await NestFactory.create(AppModule); // 新增配置:将Nest容器传入class-validator useContainer(app.select(AppModule), { fallbackOnErrors: true }); await app.listen(3000); } bootstrap();
步骤4:补全自定义装饰器定义
确保你使用的@IsUniqueUser装饰器是通过class-validator的registerDecorator方法正确注册的,示例代码如下:
import { registerDecorator, ValidationOptions } from 'class-validator'; import { UniqueValidator } from './unique.validator'; export function IsUniqueUser(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { registerDecorator({ target: object.constructor, propertyName: propertyName, options: validationOptions, constraints: [], validator: UniqueValidator }); }; }
完成以上配置后,自定义校验器就能正常注入Mongoose模型执行数据库查询了。
内容的提问来源于stack exchange,提问作者Nirjal Paudel
相关产品推荐
相关产品推荐

