2017-06-13 70 views
1

我是Express和Mongoose的新手。我正在閱讀這篇文章tutorial 以下是教程中的一個片段,其中user正在保存在數據庫中。貓鼬鉤:什麼是'這'

// Execute before each user.save() call 
UserSchema.pre('save', function(callback) { 
    var user = this; 

    // Break out if the password hasn't changed 
    if (!user.isModified('password')) return callback(); 

    // Password changed so we need to hash it 
    bcrypt.genSalt(5, function(err, salt) { 
    if (err) return callback(err); 

    bcrypt.hash(user.password, salt, null, function(err, hash) { 
     if (err) return callback(err); 
     user.password = hash; 
     callback(); 
    }); 
    }); 
}); 
  1. 到底是什麼thisthis是指新的/修改過的文檔還是this是指舊的存儲在db中?我想this是新文件。那麼有沒有關鍵字可以訪問舊文檔?在最壞的情況下,我認爲,由於這是預存儲,所以我可以使用findOne訪問舊的/保存的文檔。有沒有比這種方法更好的東西?
  2. 作者正在檢查密碼是否已更改。所以我想isModified,比較新文檔和舊文檔中的給定字段,並根據修改或不修改返回一個布爾值。問題是,保存作者保存了散列,但在檢查修改時,我想他應該先創建散列,然後檢查散列是否相同。我是對的,還是我在這裏錯過了一些東西。

回答

1

1 - pre hook在將文檔保存到數據庫之前被調用 - 因此單詞「pre」。 this在保存之前引用文檔。它將包括您對其字段所做的任何更改。

舉例來說,如果你沒有

user.password = 'newpassword'; 
user.save(); 

然後,鉤子將觸發正確的插入/更新的文件在數據庫

UserSchema.pre('save', function (next) { 
    console.log(this.password); // newpassword 
    next(); // do the actual inserting/updating 
}); 

前2 - 當編輯的用戶,你可以將表單的密碼輸入設置爲空白。空白密碼輸入通常意味着不做任何更改。如果輸入新值,則認爲更改密碼。

然後,你會改變你的架構如下圖所示:

添加setter爲您的密碼字段

let UserSchema = new mongoose.Schema({ 
    password: { 
     type: String, 
     // set the new password if it provided, otherwise use old password 
     set: function (password) { 
      return password || this.password; 
     } 
    } 
    // etc 
}); 

UserSchema.pre('save', function (next) { 
    var user = this; 
    // hash password if it present and has changed 
    if (user.password && user.isModified('password')) { 
     // update password 
    } else { 
     return next(); 
    } 
}); 

使用這種方法,您可能必須爲使用例如

var user = new User({ password: req.body.password }); 
user.save(); 

user.set({ password: req.body.password }); 
user.save(); 

不知道第一個例子將與二傳手工作。