Mongodb / Mongoose:如何在快速路线上正确实施findOneAndUpdate

时间:2017-09-27 11:58:30

标签: javascript mongodb express mongoose

我想使用findOneAndUpdate()方法更新用户在html更新表单上输入的数据更新现有模型(Account)。 因此,如果用户仅决定更新电话号码字段,则仅更新电话号码字段,并且其余两个字段保持不变。

帐户架构:

    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请求正常。我可以在get请求上访问帐户模型以向用户显示用户详细信息,但更新路由没有执行任何操作。我知道我在更新后路由设置上遗漏了一些东西。 提前谢谢。

1 个答案:

答案 0 :(得分: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;