Multer/Body-parser环境下PUT请求rooms字段返回数组的异常问题
解决Multer/Body-Parser下PUT路由中Rooms字段数组化及更新追加问题
看起来你遇到的问题根源有两个:一是表单提交后rooms被解析成了包含空字符串的数组,二是MongoDB中该字段可能已经被存储为数组类型,导致更新时新值被追加而非替换。咱们一步步来解决:
1. 先修正表单提交时的rooms值解析问题
从你给出的console.log结果rooms: [ '2', '' ]来看,大概率是表单里存在重复的name="rooms"输入框(可能是EJS渲染时的疏漏,比如循环里重复生成了),或是multer处理多部分表单时,对空值的解析逻辑导致数组出现。
先在PUT路由里强制提取有效数值,确保传入MongoDB的是单一值:
router.put("/immobili/:_id/edit", upload.fields([{ name: 'estateImages', maxCount: 30 }, { name: 'document', maxCount: 1 }]), (req, res) => { // 处理rooms字段:过滤空值后取第一个有效元素,转为数值 let rooms = req.body.rooms; if (Array.isArray(rooms)) { const validRoomVal = rooms.filter(val => val.trim() !== '')[0]; rooms = validRoomVal ? parseInt(validRoomVal) : null; } else { rooms = rooms ? parseInt(rooms) : null; } Estate.findOneAndUpdate( { _id: req.params._id }, // 注意这里你代码里的requestedId应该是req.params._id { rooms: rooms, // 现在是单一数值 squareFeets: parseInt(req.body.squareFeets), // 其他字段... }, { new: true, runValidators: true }, // 关键选项:返回更新后的文档,强制运行模型验证 (err, updatedEstate) => { if (err) { console.error(err); return res.redirect('/some-error-page'); } res.redirect(`/estates/${updatedEstate._id}`); } ) })
2. 确保MongoDB模型中rooms字段的类型正确
检查你的Estate模型定义,必须确保rooms是Number类型,而不是Array——这是更新时不会追加的核心前提:
const estateSchema = new mongoose.Schema({ rooms: { type: Number, required: true // 根据业务需求添加必填验证 }, squareFeets: { type: Number, required: true }, // 其他字段... }); const Estate = mongoose.model('Estate', estateSchema);
如果之前的rooms字段已经被错误存储为数组,你需要先迁移现有数据(比如把数组转为第一个有效元素的数值),否则即使路由里处理了,MongoDB可能因类型不匹配导致异常。
3. 检查EJS表单是否存在重复的rooms输入框
仔细核对你的EJS代码,确保只渲染了一个name="rooms"的输入框,同时加上type="number"规范输入:
<form action="/estates/<%= estate._id %>/edit?_method=PUT" method="POST" enctype="multipart/form-data"> <!-- 确保唯一的rooms输入框,限制为数字类型 --> <input name="rooms" type="number" value="<%= estate.rooms %>"> <!-- 正常输入框 --> <input name="superficie" type="number" value="<%= estate.squareFeets %>"> <input type="submit" value="Publish"> </form>
另外注意:你代码里表单输入框的name="superficie",但路由里用的是req.body.squareFeets,这应该是笔误,建议统一字段名避免后续问题。
按照上面的步骤调整后,rooms字段应该会被正确存储为单一数值,更新时也会替换旧值而非追加。
内容的提问来源于stack exchange,提问作者Mattia Rasulo
相关产品推荐
相关产品推荐

