点餐应用创建订单时同步生成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
相关产品推荐
相关产品推荐

