2017-09-27 11 views
1

findOneAndUpdate()メソッドを使用して、ユーザーがhtml更新フォームに入力したデータで既存のモデル(Account)を更新します。 したがって、ユーザーが電話番号フィールドの更新のみを決定する場合は、電話番号フィールドのみが更新され、残りの2つのフィールドは同じままになります。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要求が正常に動作します。ユーザーの詳細をユーザーに表示するget要求でアカウントモデルにアクセスできますが、更新ルートは何もしていません。私は、アップデートポストルート設定で何かが欠けていることを知っています。 ありがとうございます。

答えて

0

編集:あなたはfindByIdAndUpdateが間違っていることを知りました。私の最初の答えはまだ有効ですが、これの後に見つけることができます。 findByIdAndUpdate第2引数はコールバックではなく、変更する値を含むオブジェクトです。正しく使用すると、要求の最後に.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 
}); 

ORIGINAL ANSWER: doc.save()findByIdAndUpdateと同じように、コールバックを取ります。したがって、save関数の中に別のコールバックをネストしなければなりません。リダイレクトすることができます。ここで

は、私は(約束を使用して)それを行うだろう方法は次のとおりです。

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

こんにちはデビッド、ありがとう迅速な返信のために...私はちょうど1つの質問があります。 2番目の例(約束を使って)がうまくいく前に私は約束をインストールする必要がありますか? – omosofe

+0

はい、mongoose自身の約束ライブラリは廃止予定ですので、外部の約束ライブラリを使用する必要があります。私は約束を含めるように私の答えを更新するでしょう:) –

+0

デビッドは、あなたのコードレビューでいくつかの調整をした後、私のアップデートルートを稼働させることができました。後で私の解決策を掲載します。私は仕上げを待つことができません。 もう一度感謝します。 – omosofe

関連する問題