2017-09-27 89 views
1

我想使用findOneAndUpdate()方法来更新用户在html更新表单上输入的数据更新现有模型(Account)。 因此,如果用户只决定更新电话号码字段,则只更新电话号码字段,剩下的两个字段保持不变。Mongodb/Mongoose:如何在快速路径上正确实现findOneAndUpdate

账户模式:

var mongoose = require('mongoose'); 
    var Schema = mongoose.Schema; 

    var accountSchema = new Schema({ 
    // Reference to the user model in session. 
    user: {type: Schema.Types.ObjectId, ref: 'User'}, 

    // User's account information displayed on user's home page 
    first_name : {type: String}, 
    last_name : {type: String}, 
    phone_number: {type: String} 

    }, 
    {timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }} 
    ); 

    module.exports = mongoose.model('Account', accountSchema); 

这里是我的路线代码:

app.get('/support', isLoggedIn, function (req, res, next) { 
     var account = Account({user: req.user}); 
     Account.findOne({user: req.user}, function(err, account) { 
     if (err) { 
      res.send(500); 
      return; 
     } 
     console.log(account.first_name) 
     res.render('support', {user: req.user, account: account}); 
     }); 
    }); 

    app.post('/support', isLoggedIn, function(req, res, next) { 
     var id = req.params.account._id; 

     Account.findByIdAndUpdate(id, function(err, doc) { 
     if (err) { 
      console.error('error, no entry found'); 
     } 
     doc.first_name = req.body.first_name || doc.first_name; 
     doc.last_name = req.body.last_name || doc.last_name; 
     doc.phone_number = req.body.phone_number || doc.phone_number; 
     doc.save(); 
     }) 
     res.redirect('/home'); 
    }); 

GET请求工作正常。我可以访问获取请求上的帐户模型,以向用户显示用户详细信息,但更新路由没有任何操作。我知道我在更新帖子路线设置中丢失了一些东西。 在此先感谢。

回答

0

编辑:我刚刚意识到你正在使用findByIdAndUpdate错误。我的第一个答案仍然有效,可以在此之后找到。 findByIdAndUpdate第二个参数不是回调,而是包含要更改的值的对象。正确使用时,您不必在请求结束时致电.save()。 因此,更新架构的正确的方法是这样的:

Account.findByIdAndUpdate(req.params.account._id, { 
    $set:{ 
     first_name: req.body.first_name, 
     // etc 
    } 
}, {new: true}, function(err, updatedDoc){ 
    // do stuff with the updated doc 
}); 

原来的答案:doc.save()也需要一个回调,就像findByIdAndUpdate一样。所以你必须在你的保存功能中嵌套另一个回调,然后你可以重定向。

这是我怎么会做它(使用承诺):

app.post('/support', function(req, res, next){ 
    Account.findOne({_id: req.params.account._id}).exec() 
    .then(function(doc){ 
     doc.first_name = req.body.first_name || doc.first_name; 
     // etc ... 
     return doc.save(); 
    }) 
    .then(function(){ 
     // Save successful! Now redirect 
     res.redirect('/home'); 
    }) 
    .catch(function(err){ 
     // There was an error either finding the document or saving it. 
     console.log(err); 
    }); 
}); 

这里是你如何包括外部承诺库 - 我使用的'q' library

// app.js 
const mongoose = require('mongoose'); 
mongoose.Promise = require('q').Promise; 
+0

嗨大卫,谢谢为了迅速回复......我只有一个问题。我需要在第二个例子(使用promise)之前安装Promise吗? – omosofe

+0

是的,您必须使用外部承诺库,因为猫鼬的承诺库已被弃用。我会更新我的答案,包括承诺:) –

+0

非常感谢大卫,经过与您的代码审查调整后,我能够让我的更新路线工作。我将在稍后发布我的解决方案。我迫不及待想要完成。 再次非常感谢。 – omosofe