如何通过POST提交Plan数据并关联至仅支持GET的PlanDetails路由?
问题描述
我想让PlanDetailsSchema关联PlanSchema,但目前无法实现。两者属于不同路由,PlanDetailsSchema只提供GET路由,要求在向PlanSchema发送POST请求时,生成的Plan数据能被PlanDetailsSchema关联获取。当前getPlanDetails接口返回空数组,既无法获取关联的Plan数据,也没有返回默认的status值。
原代码
PlanSchema
import mongoose from "mongoose"; export interface IPlan { planName: string; personalName: string; } const PlanSchema = new mongoose.Schema<IPlan>( { planName: { type: String, required: [true, "Please provide plan name"], }, personalName: { type: String, required: [true, "Please provide personal name"], }, }, { timestamps: true } ); export default mongoose.model<IPlan>("Plan", PlanSchema);
PlanDetailsSchema
import mongoose, { SchemaTypes } from "mongoose"; import { IPlan } from "./Plan"; interface IPlanDetails { planSchema: IPlan; status: "Processing" | "Active" | "Expired" | "Declined" | "Refunded"; } const PlanDetailsSchema = new mongoose.Schema<IPlanDetails>({ planSchema: { type: SchemaTypes.ObjectId, ref: "Plan", }, status: { type: String, default: "Processing", enum: { values: ["Processing", "Active", "Expired", "Declined", "Refunded"], message: "{VALUE} is not supported", }, }, }); export default mongoose.model<IPlanDetails>("PlanDetails", PlanDetailsSchema);
addPlan(POST路由)
const addPlan = async (req: Request, res: Response) => { const plan = await new Plan(...req.body); res.status(201).json({ plan }); }
getPlanDetails(GET路由)
export const getPlanDetails = async (req: Request, res: Response) => { const planDetails = await PlanDetails.find({}).populate("Plan"); res.status(200).json({ planDetails }); };
当前接口返回
{ "planDetails": [] }
错误分析与修正方案
核心问题
- POST创建Plan时未同步生成PlanDetails:
addPlan仅创建Plan记录,未生成关联的PlanDetails,导致PlanDetails集合为空 - populate参数错误:
populate应传入字段名planSchema,而非模型名Plan - TypeScript接口不匹配:
IPlanDetails中planSchema的类型应为ObjectId,而非IPlan
修正后的代码
修正PlanDetailsSchema接口与定义
import mongoose, { SchemaTypes, Types } from "mongoose"; import { IPlan } from "./Plan"; interface IPlanDetails { planSchema: Types.ObjectId; // 修正为ObjectId类型,匹配Schema定义 status: "Processing" | "Active" | "Expired" | "Declined" | "Refunded"; } const PlanDetailsSchema = new mongoose.Schema<IPlanDetails>({ planSchema: { type: SchemaTypes.ObjectId, ref: "Plan", required: true // 强制关联Plan,确保数据完整性 }, status: { type: String, default: "Processing", enum: { values: ["Processing", "Active", "Expired", "Declined", "Refunded"], message: "{VALUE} is not supported", }, }, }); export default mongoose.model<IPlanDetails>("PlanDetails", PlanDetailsSchema);
修正addPlan路由(同步创建关联记录)
import Plan from './path-to-plan-model'; import PlanDetails from './path-to-plan-details-model'; const addPlan = async (req: Request, res: Response) => { // 1. 创建并保存Plan记录 const plan = new Plan(req.body); // 修正参数传递方式,直接传入请求体对象 await plan.save(); // 2. 基于新Plan生成关联的PlanDetails const planDetails = new PlanDetails({ planSchema: plan._id // 关联新Plan的ObjectId }); await planDetails.save(); res.status(201).json({ plan, planDetails }); }
修正getPlanDetails路由(正确关联查询)
import PlanDetails from './path-to-plan-details-model'; export const getPlanDetails = async (req: Request, res: Response) => { // populate传入字段名planSchema,自动关联填充Plan数据 const planDetails = await PlanDetails.find({}).populate("planSchema"); res.status(200).json({ planDetails }); };
修正后效果
- 调用POST接口创建Plan时,会自动生成带默认
status: "Processing"的PlanDetails记录 - 调用GET接口时,返回的每个PlanDetails都会包含完整的关联Plan数据
内容的提问来源于stack exchange,提问作者coderx
相关产品推荐
相关产品推荐

