我是Express和Mongoose的新手。我正在读这个tutorial
这是教程中的一个片段,其中user
正在db中保存。
// 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();
});
});
});
this
。 this
表示新/已修改的文档,或this
表示存储在数据库中的旧文档?我想this
是新文件。那么有没有关键字来访问旧文档?在最坏的情况下,我认为,由于这是预先保存,我可以使用findOne
访问旧的/已保存的文档。有没有比这种方法更好的东西?isModified
,比较新文档和旧文档中的给定字段,并根据修改返回bool。问题是,虽然保存作者已经保存了哈希,但在检查修改时,我想他应该首先创建哈希,然后检查哈希值是否相同。我是对的,还是我在这里遗漏了一些东西。答案 0 :(得分:1)
1 - 在将文档保存到数据库之前调用pre
挂钩 - 因此单词“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();
不确定第一个示例是否适用于setter。