为何func2无需设置ValidateBeforeSave:false即可运行,而func1却不行?
为何func1必须关闭保存验证,而func2不需要?
核心原因:Schema验证规则与字段存在性的差异
1. 先明确Schema的关键验证逻辑
你的用户Schema中,passwordConfirm字段包含两个强制验证:
passwordConfirm: { required: [true, 'password confimr must be set'], validate: { validator: function (val) { return val === this.password; }, }, },
同时在实际用户认证场景中,通常会通过pre save钩子在首次保存用户时移除passwordConfirm(不需要将确认密码存入数据库),示例钩子代码如下:
userSchema.pre('save', function(next) { if (!this.isModified('password')) return next(); // 此处一般会对password进行加密处理 this.passwordConfirm = undefined; // 移除确认密码字段,不存入数据库 next(); });
这意味着:从数据库查询返回的用户文档不包含passwordConfirm字段。
2. func1的执行问题
- 通过
User.findOne取出用户后,文档中没有passwordConfirm字段 - 调用
createResetToken仅修改了passwordResetToken,未设置passwordConfirm - 执行
user.save()时,mongoose会触发所有字段的验证规则:passwordConfirm的required验证直接失败(字段不存在)- 因此必须添加
{ validateBeforeSave: false }跳过所有验证,才能成功保存
3. func2能正常运行的原因
- 同样取出无
passwordConfirm字段的用户文档 - 手动设置了
user.password和user.passwordConfirm:- 满足
passwordConfirm的required规则(字段有值) - 自定义验证器通过(
passwordConfirm与password值完全一致)
- 满足
- 所有验证规则都符合要求,因此无需关闭验证即可成功执行
user.save()
内容的提问来源于stack exchange,提问作者Sajjad Jafari
相关产品推荐
相关产品推荐

