Nest中使用Typegoose实现多对多时报Invalid model object错误
解决Typegoose + NestJS中"Invalid model object"错误及实现多对多关联
问题背景
在Typegoose中尝试实现多对多关联时,执行getModelForClass(Portfolio)抛出Error: Invalid model object错误,错误堆栈指向nestjs-typegoose的模型转换逻辑。
错误根源
从错误堆栈及代码分析,核心问题有两点:
- 直接在类文件中调用
getModelForClass生成模型,再传入NestJS的TypegooseModule.forFeature,导致重复初始化触发校验失败 - 混淆了类定义与模型实例的传递方式,不符合
nestjs-typegoose的集成规范
修复步骤
1. 调整模型文件:仅导出类,不预生成模型
修改portfolio.model.ts(建议将原portfolio.service.ts重命名为该名称,区分模型与业务逻辑):
import { prop } from "@typegoose/typegoose"; import { Base, TimeStamps } from "@typegoose/typegoose/lib/defaultClasses"; import { Types } from "mongoose"; import { Services } from "./services.model"; export interface Portfolio extends Base {} export class Portfolio extends TimeStamps { @prop() title: string; @prop() description: string; @prop() status: boolean; @prop() client: string; @prop() location: string; @prop() publishedDate: string; // 多对多关联:关联多个Services @prop({ ref: () => Services, type: () => [Types.ObjectId] }) services: Types.ObjectId[]; }
修改services.model.ts:
import { prop } from "@typegoose/typegoose"; import { Base, TimeStamps } from "@typegoose/typegoose/lib/defaultClasses"; import { Types } from "mongoose"; import { Portfolio } from "./portfolio.model"; export interface Services extends Base {} export class Services extends TimeStamps { @prop() name: string; @prop() description: string; // 多对多关联:关联多个Portfolio @prop({ ref: () => Portfolio, type: () => [Types.ObjectId] }) portfolios: Types.ObjectId[]; }
2. 正确配置NestJS模块
在portfolio.module.ts中,通过TypegooseModule.forFeature传入类定义,而非预生成的模型:
import { Module } from '@nestjs/common'; import { TypegooseModule } from 'nestjs-typegoose'; import { Portfolio } from './portfolio.model'; import { Services } from '../services/services.model'; import { PortfolioService } from './portfolio.service'; import { PortfolioController } from './portfolio.controller'; @Module({ imports: [ TypegooseModule.forFeature([Portfolio, Services]) ], providers: [PortfolioService], controllers: [PortfolioController] }) export class PortfolioModule {}
3. 在Service中注入模型
在portfolio.service.ts中,使用InjectModel注入Typegoose模型:
import { Injectable } from '@nestjs/common'; import { InjectModel } from 'nestjs-typegoose'; import { Portfolio } from './portfolio.model'; import { ReturnModelType } from '@typegoose/typegoose'; @Injectable() export class PortfolioService { constructor( @InjectModel(Portfolio) private readonly portfolioModel: ReturnModelType<typeof Portfolio> ) {} // 示例:创建带关联服务的作品集 async createPortfolioWithServices(data: { title: string; description: string; serviceIds: string[]; }) { return this.portfolioModel.create({ ...data, services: data.serviceIds }); } }
4. 验证tsconfig配置
你的tsconfig.json已开启emitDecoratorMetadata和experimentalDecorators,符合Typegoose的编译要求,无需修改。
关键说明
nestjs-typegoose的forFeature方法仅接收类定义,不能传入getModelForClass生成的模型实例,否则会触发"Invalid model object"校验错误- 多对多关联通过
@prop({ ref: 关联类, type: () => [Types.ObjectId] })实现,使用函数式引用可避免循环导入问题
内容的提问来源于stack exchange,提问作者Baxa Developer
相关产品推荐
相关产品推荐

