社交网站回复功能故障:刷新后消失且用户信息不显示
问题与解决方案
当前遇到的问题
- 新增的回复已存入数据库,但页面刷新后就消失
- 回复无法显示用户名和头像
- 疑问:旧版嵌套回复的Post Schema是否支持回复的删除与编辑功能
相关代码
旧版Post Model
import mongoose from "mongoose"; const postSchema = mongoose.Schema({ postedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, text: { type: String, maxLength: 500 }, img: { type: String, }, likes: [{ // array of user id's type: mongoose.Schema.Types.ObjectId, ref: "User", default: [] }], saves: [{ // array of user id's type: mongoose.Schema.Types.ObjectId, ref: "User", default: [] }], replies: [ { userId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, text: { type: String, required: true }, userProfilePic: { type: String }, username: { type: String } } ] }, {timestamps: true} ) const Post = mongoose.model('Post', postSchema); export default Post;
新版Post Model
import mongoose from "mongoose"; const postSchema = mongoose.Schema({ postedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, text: { type: String, maxLength: 500 }, img: { type: String, }, video: { type: String, ref: "Upload" }, likes: [{ // array of user id's type: mongoose.Schema.Types.ObjectId, ref: "User", default: [] }], saves: [{ // array of user id's type: mongoose.Schema.Types.ObjectId, ref: "User", default: [] }], replies: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Replies', userId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, }] }, {timestamps: true} ) const Post = mongoose.model('Post', postSchema); export default Post;
Reply Model
import mongoose from "mongoose"; const ReplySchema = mongoose.Schema({ text: { type: String, required: true }, tag: Object, reply: mongoose.Types.ObjectId, likes: [{ type: mongoose.Types.ObjectId, ref: 'User' }], user: { type: mongoose.Types.ObjectId, ref: "User" }, }, { timestamps: true }) const Reply = mongoose.model('Replies', ReplySchema); export default Reply;
Controller函数
const replyCtrl = { createReply: async(req, res) => { try { const { postId, text, tag, comment } = req.body; const newReply = new Reply({ user: req.user._id, text, tag, comment }) await Post.findOneAndUpdate({_id: postId}, { $push: {replies: newReply._id} }, {new: true}) await newReply.save(); res.status(200).json(newReply) } catch (err) { console.log(err) } } }
问题解决
1. 回复刷新消失+不显示用户名/头像的原因及修复
核心问题:
- 新版Post模型的
replies字段定义冗余:嵌套的userId完全多余,用户信息已存储在Reply模型中,正确定义应为单纯的ObjectId数组关联Replies - 获取帖子数据时未执行关联查询(populate),无法拿到回复及对应的用户信息
修复步骤:
第一步:修正新版Post模型的replies字段
// 替换原有replies字段定义 replies: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Replies' }]
第二步:修改createReply控制器,返回关联用户信息的回复
const replyCtrl = { createReply: async(req, res) => { try { const { postId, text, tag, comment } = req.body; const newReply = new Reply({ user: req.user._id, text, tag, reply: comment // 参数名与Reply模型字段保持一致 }) // 先保存回复,再更新帖子关联关系 await newReply.save(); await Post.findOneAndUpdate({_id: postId}, { $push: {replies: newReply._id} }, {new: true}) // 关联查询用户信息后返回,仅获取需要的字段 const populatedReply = await Reply.findById(newReply._id).populate('user', 'username profilePic'); res.status(200).json(populatedReply) } catch (err) { console.log(err) res.status(500).json({msg: '创建回复失败'}) } } }
第三步:获取帖子时关联回复及用户信息
在获取帖子的接口中,需要嵌套关联查询:
const posts = await Post.find() .populate('postedBy', 'username profilePic') .populate({ path: 'replies', populate: { path: 'user', select: 'username profilePic' // 仅返回用户名和头像字段 } })
2. 旧版嵌套Schema能否实现回复的删除与编辑?
完全可以,利用Mongoose的数组操作符即可实现:
编辑回复
// 编辑指定帖子下的指定回复 const editReply = async(req, res) => { try { const { postId, replyId, newText } = req.body; await Post.findOneAndUpdate( { _id: postId, 'replies._id': replyId }, // 定位目标帖子与回复 { $set: { 'replies.$.text': newText } }, // $表示匹配到的数组元素 { new: true } ) res.status(200).json({msg: '回复编辑成功'}) } catch (err) { console.log(err) res.status(500).json({msg: '编辑失败'}) } }
删除回复
// 删除指定帖子下的指定回复 const deleteReply = async(req, res) => { try { const { postId, replyId } = req.body; await Post.findOneAndUpdate( { _id: postId }, { $pull: { replies: { _id: replyId } } }, // 从数组中移除指定ID的回复 { new: true } ) res.status(200).json({msg: '回复删除成功'}) } catch (err) { console.log(err) res.status(500).json({msg: '删除失败'}) } }
内容的提问来源于stack exchange,提问作者khayal
相关产品推荐
相关产品推荐

