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

点餐应用创建订单时同步生成User对象报错求助

问题描述

我正在开发一款无需强制登录的点餐应用,用户可在下单时提供信息完成订购。希望创建订单的同时自动生成对应的User对象,但创建订单时出现错误,相关代码及错误信息如下:

Model - Order

const mongoose = require('mongoose');
const User = require('./User')
const Meal = require('./Meal')
const OrderSchema = new mongoose.Schema(
  {
    customer: {
      type: mongoose.Schema.Types.ObjectId,
      ref: User,
      required: true
    },
    orderedmeal: {
      type: mongoose.Schema.Types.ObjectId,
      ref: Meal,
      required: true
    },
    ordertotal: {
      type: Number,
      required: false,
      default:0
    },
    dateOrder: String,
    status: {
      type: Boolean,
      default: false
    },
  },
  { timestamps: true }
);

module.exports = mongoose.model("Order", OrderSchema);

Controller - create Order

exports.createOrder = async (req, res) => {

  const newOrder = new Order(req.body)
  newOrder.save();

  return res.status(200).json({
    customer: newOrder.customer, 
    orderedmeal: newOrder.orderedmeal,
    ordertotal: newOrder.ordertotal,
    dateOrder: newOrder.dateOrder,
    status : newOrder.status
  })
}

Orderform(前端代码)

const [order, setOrder] = useState();
  
  const handleSubmit = async (e) => {
      e.preventDefault();
      try {
        const res = await axios.post(GET_ORDERS_URL, {
          customer: {
            firstname: firstname,
            lastname: lastname,
            numTel: numTel,
            address: address,
          },
          orderedmeal: orderedmeal,
          ordertotal: orderTotal,
          dateOrder: dateOrder,
        });

        setOrder(res.data);
        console.log("Order ", order);
      } catch (error) {
        console.log(error);
      }
  };

控制台错误信息

this.$__.validationError = new ValidationError(this);
                                ^

 ValidationError: Order validation failed: customer: Cast to ObjectId failed for value "{
   firstname: 'djamila',
   lastname: 'azouane',
   numTel: '0777776602',
   address: 'Hussein Dey'
 }" (type Object) at path "customer" because of "BSONTypeError"
     at model.Document.invalidate (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:3054:32)
     at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1409:12)
     at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1092:16)
     at model.Document (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:166:12)
     at model.Model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:119:12)
     at new model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:4999:15)
     at exports.createOrder (C:\Users\hp\Documents\booking\server\Controllers\order.js:9:20)
     at Layer.handle [as handle_request] (C:\Users\hp\Documents\booking\server\node_modules\express\lib\router\layer.js:95:5)
     at next (C:\Users\hp\Documents\booking\server\node_modules\express\lib\router\route.js:144:13)
     at next (C:\Users\hp\Documents\booking\server\node_modules\express\lib\router\route.js:138:14) {
   errors: {
     customer: CastError: Cast to ObjectId failed for value "{
       firstname: 'djamila',
       lastname: 'azouane',
       numTel: '0777776602',
       address: 'Hussein Dey'
     }" (type Object) at path "customer" because of "BSONTypeError"
         at ObjectId.cast (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\schema\objectid.js:248:11)
         at ObjectId.SchemaType.applySetters (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\schematype.js:1201:12)    
         at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1367:22)
         at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1092:16)
         at model.Document (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:166:12)
         at model.Model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:119:12)
         at new model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:4999:15)
         at exports.createOrder (C:\Users\hp\Documents\booking\server\Controllers\order.js:9:20)
         at Layer.handle [as handle_request] (C:\Users\hp\Documents\booking\server\node_modules\express\lib\router\layer.js:95:5)      
         at next (C:\Users\hp\Documents\booking\server\node_modules\express\lib\router\route.js:144:13) {
       stringValue: '"{\n' +
         "  firstname: 'djamila',\n" +
         "  lastname: 'azouane',\n" +
         "  numTel: '0777776602',\n" +
         "  address: 'Hussein Dey'\n" +
         '}"',
       messageFormat: undefined,
       kind: 'ObjectId',
       value: {
         firstname: 'djamila',
         lastname: 'azouane',
         numTel: '0777776602',
         address: 'Hussein Dey'
       },
       path: 'customer',
       reason: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer
           at new BSONTypeError (C:\Users\hp\Documents\booking\server\node_modules\bson\lib\error.js:41:28)
           at new ObjectId (C:\Users\hp\Documents\booking\server\node_modules\bson\lib\objectid.js:67:23)
           at castObjectId (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\cast\objectid.js:25:12)
           at ObjectId.cast (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\schema\objectid.js:246:12)
           at ObjectId.SchemaType.applySetters (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\schematype.js:1201:12)  
           at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1367:22)
           at model.$set (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:1092:16)
           at model.Document (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\document.js:166:12)
           at model.Model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:119:12)
           at new model (C:\Users\hp\Documents\booking\server\node_modules\mongoose\lib\model.js:4999:15),
       valueType: 'Object'
     }
   },
   _message: 'Order validation failed'
 }
 [nodemon] app crashed - waiting for file changes before starting...
错误原因

Order模型中customer字段定义为ObjectId类型,要求存储对应User文档的ID,但当前前端传入的是完整的用户信息对象,后端控制器直接用req.body创建Order,没有先创建User并获取其ID,导致类型不匹配,触发CastError。

解决方案

修改订单创建控制器,先从请求体中提取用户信息创建User,再用生成的User ID创建Order,同时修复异步操作缺失的await:

exports.createOrder = async (req, res) => {
  try {
    // 1. 从请求体中提取用户信息并创建User
    const { customer, ...orderData } = req.body;
    const newUser = await new User(customer).save();

    // 2. 使用生成的User ID创建Order
    const newOrder = new Order({
      ...orderData,
      customer: newUser._id // 传入User的ObjectId
    });
    await newOrder.save();

    // 3. 返回包含用户信息的订单数据(可选,方便前端展示)
    const populatedOrder = await Order.findById(newOrder._id).populate('customer');
    return res.status(201).json(populatedOrder);
  } catch (error) {
    return res.status(400).json({ error: error.message });
  }
};

关键修改点

  • 解构请求体,分离用户信息和订单其他数据
  • 先创建并保存User,获取其自动生成的_id
  • 将User的_id赋值给Order的customer字段,匹配模型类型要求
  • 为所有异步操作添加await,确保操作按顺序执行
  • 添加错误捕获,返回清晰的错误响应
  • 可选:使用populate返回包含完整用户信息的订单数据,减少前端二次请求
额外说明

前端代码无需修改,传入的用户信息结构符合User模型要求,后端会自动处理User的创建逻辑。

内容的提问来源于stack exchange,提问作者Djamila Azouane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:30:30