Node.js关联RoomSchema到UserSchema时遇push属性未定义错误
问题解决:Cannot read properties of undefined (reading 'push')
错误根源
你的代码中调用user.rooms.push(roomId)时出现报错,原因有两点:
- Schema定义不匹配:
UserSchema里定义的是单个关联字段room(类型为ObjectId),但接口代码中试图访问的是rooms数组属性,这个属性在Schema中不存在。 - 现有文档无对应字段:当前用户文档中也没有
rooms字段,导致user.rooms为undefined,无法调用push方法。
解决方案
根据你的业务需求(用户是否可加入多个房间),选择以下两种方案之一:
方案1:支持用户加入多个房间(多对多关系)
如果允许用户加入多个房间,需要先修改UserSchema,将单个字段改为数组类型:
const UserSchema = new Schema({ name: String, email: { type: String, unique: true, required: true }, password: { type: String, required: true }, rooms: [{ type: Schema.Types.ObjectId, ref: "Room" }] // 修改为数组类型 });
然后调整接口代码,推荐使用MongoDB的$addToSet操作符(避免重复添加同一房间),同时兼容无rooms字段的旧文档:
router.post('/join-room', async (req, res) => { const { roomId, userId } = req.body; try { const user = await User.findById(userId); const room = await Room.findById(roomId); if (!user || !room) { return res.status(404).json({ message: 'User or room not found' }); } // 使用$addToSet确保不重复添加,同时自动初始化数组(如果不存在) await User.updateOne( { _id: userId }, { $addToSet: { rooms: roomId } } ); res.json({ message: 'User joined room successfully' }); } catch (error) { console.error(error); res.status(500).json({ message: 'Server error' }); } });
如果仍想使用push方法,需先初始化数组:
// 在push前添加判断 if (!user.rooms) { user.rooms = []; } user.rooms.push(roomId); await user.save();
方案2:用户只能加入一个房间(一对一关系)
如果用户只能加入一个房间,保持UserSchema不变,修改接口代码为直接赋值:
router.post('/join-room', async (req, res) => { const { roomId, userId } = req.body; try { const user = await User.findById(userId); const room = await Room.findById(roomId); if (!user || !room) { return res.status(404).json({ message: 'User or room not found' }); } user.room = roomId; // 直接赋值替换原有房间 await user.save(); res.json({ message: 'User joined room successfully' }); } catch (error) { console.error(error); res.status(500).json({ message: 'Server error' }); } });
额外注意事项
- 修改Schema后,需要重启Node.js服务才能生效。
- 若选择多房间方案,可通过MongoDB命令批量初始化现有用户的
rooms数组:
# 在MongoDB Shell中执行 db.users.updateMany({}, { $set: { rooms: [] } })
内容的提问来源于stack exchange,提问作者jibzy
相关产品推荐
相关产品推荐

