如何在猫鼬中重用中间件前功能

时间:2020-10-17 18:48:32

标签: javascript mongodb mongoose

我需要在另一个前置中间件中重用一个前置中间件功能,因为我提取了这样一个功能:

async function encryptPassword(next) {
    if (!this.isModified('password')) {
        return next();
    }
    this.password = await bcrypt.hash(this.password, 5);
    this.passwordChangedAt = new Date();
    next();
}

UserSchema.pre('save', encryptPassword);

UserSchema.pre("findOneAndUpdate", encryptPassword);

但是我收到一个错误消息,说this.isModified不是函数,我假设this指的是其他内容。该如何解决?

1 个答案:

答案 0 :(得分:1)

在调试器和文档的帮助下,我深入了这些前/后钩子,发现了几件事情(它们同时适用于prepost):

使用save钩子意味着this引用文档本身。因此,您可以更新其字段,调用isModified之类的方法,等等。以上方法应该不会有任何问题。

但是,findOneAndUpdate钩子意味着this引用的是查询而不是文档。 Query对象将没有文档或其继承的方法(如isModified)。

我与调试器进行了检查,可以确认是否是这种情况(有关文档的最新信息)。

钩子列表:https://mongoosejs.com/docs/middleware.html#types-of-middleware

您将看到只有以下挂钩允许修改文档:

validate
save
remove
updateOne
deleteOne
init (note: init hooks are synchronous)

其他所有人都不会。看来这是故意的(https://github.com/Automattic/mongoose/issues/964)。

要解决findOneAndUpdate的问题,似乎(最相似)唯一的方法是将findOneupdateOne做为单独的查询进行重做。