在猫鼬中进行预更新时,user.isModified 不是函数
Posted
技术标签:
【中文标题】在猫鼬中进行预更新时,user.isModified 不是函数【英文标题】:user.isModified is not a function when doing a pre update in mongoose 【发布时间】:2017-03-02 20:50:49 【问题描述】:我正在尝试在我正在构建的应用程序中对密码进行哈希处理,当我通过调用此函数 (coffeesctipt) 创建用户时,它们的哈希处理效果很好:
UserSchema.pre 'save', (next) ->
user = this
hashPass(user, next)
hashPass = (user, next) ->
# only hash the password if it has been modified (or is new)
if !user.isModified('password')
return next()
# generate a salt
bcrypt.genSalt SALT_WORK_FACTOR, (err, salt) ->
if err
return next(err)
# hash the password using our new salt
bcrypt.hash user.password, salt, (err, hash) ->
if err
return next(err)
# override the cleartext password with the hashed one
user.password = hash
next()
return
return
但是当我进行更新并拥有此预置时:
UserSchema.pre 'findOneAndUpdate', (next) ->
user = this
hashPass(user, next)
我得到TypeError: user.isModified is not a function
如果我在 pres 控制台登录用户保存 pre 记录我正在更新的用户,findandupdate pre 没有,id 有办法访问 pres 中的文档还是我需要这样做另一种方式?
【问题讨论】:
我遇到了同样的问题,但我的问题是在尝试 User.Create 和 new User() 然后 user.save() 我认为你的问题是.pre('update')
钩子中的this
指的是Query
对象而不是模型本身:mongoosejs.com/docs/middleware.html#notes
【参考方案1】:
不要在回调中使用箭头操作符,这会改变 this 的范围。定义一个常规函数;它可能会帮助您解决这个问题。
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:在 mongoose 中使用中间件时要小心,在“save”或“updateOne”的情况下,this
指的是查询,而不是文档。它应该是这样的
schema.pre(type, document: true, query: false , async function (next)
if(this.isModified('password'))
//Do the hash
next();
);
【讨论】:
【参考方案3】:我知道这对您来说可能为时已晚,但对于任何未来遇到此问题的编码人员,我认为此解决方案应该可行。 因此,由于 save() 是 .pre 中的中间件,它覆盖了一些 mongoose 的方法,例如 findByIDAndUpdate。如果您在某处触发了补丁请求,您可能想要做的不是使用它,而是像这样分解您的代码:
const user = await User.findById(req.params.id);
updates.forEach((update) =>
user[update] = req.body[update];
);
【讨论】:
【参考方案4】:您收到错误消息,因为箭头函数更改了“this”的范围。 只需使用
UserSchema.pre('save', function(next))
【讨论】:
问题出在CoffeeScript中,CoffeeScript将箭头函数编译成UserSchema.pre('save', function(next))
而不是js箭头函数【参考方案5】:
我在 typescript 上遇到了类似的问题,事实证明这与您也在使用的箭头运算符有关。不知道现在如何在 coffescript 中更改它,但我认为这应该可以解决您的问题。
你必须改变这一行:
hashPass = (user, next) ->
看看这个:https://github.com/Automattic/mongoose/issues/4537
【讨论】:
->
只是你在咖啡脚本中编写函数的方式,它编译成一个普通函数而不是 =>
您的问题与我的问题完全相同。我在答案中链接的 github 问题向您解释了原因。看看吧。
我确实检查过,咖啡中的UserSchema.pre 'findOneAndUpdate', (next) ->
编译为UserSchema.pre('findOneAndUpdate', function(next)
,因此我几乎无法更改我的代码以使其基于该解决方案工作。我的问题是因为 Model.pre 'findOneAndUpdate' 返回的 this
与 Model.pre 'save' 不同。 pre 'save' 将用户返回为 'this' 而 pre on findOneAndUpdate 不会。
我明白了,我正在做一些更多的研究,根据这个讨论似乎不可能完成你想要做的事情:github.com/Automattic/mongoose/issues/964。在线程上有一些您可以使用的建议以上是关于在猫鼬中进行预更新时,user.isModified 不是函数的主要内容,如果未能解决你的问题,请参考以下文章