You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:12:19