我正在尝试验证猫鼬模式,但我无法理解一件事,即类型验证。我正在将数字类型传递给字符串字段,并期望它无法通过验证,但可以通过。这是怎么回事,任何人都可以解释一下这背后的逻辑吗?
sample.js
const mongoose = require('mongoose');
async function validateSample(sample) {
try {
await sample.validate();
return true;
} catch (error) {
return false;
}
}
async function execMethod(){
var userSchema = new mongoose.Schema({
phone: {
type: String,
minlength: 2,
maxlength: 4,
validate: {
validator: function(v) {
return /^\d+$/.test(v);
},
message: `not a valid phone number!`
},
required: [true, 'User phone number required']
}
});
var User = mongoose.model('user', userSchema);
var validUser = new User({phone: '1234'});
var invalidUser = new User({phone: 1235});
const result = await validateSample(validUser);
const result1 = await validateSample(invalidUser);
console.log(result); // true
console.log(result1) // expected false as number type is assigned to phone. But returns true, why?
}
execMethod()
答案 0 :(得分:2)
这实际上是猫鼬验证的a feature。
在运行验证器之前,猫鼬会尝试将值强制转换为 正确的类型。此过程称为投射文档。如果对于给定的路径转换失败,则error.errors对象将包含一个
CastError
对象。铸造在验证之前运行,并且如果投放失败,验证不会运行。
在这种情况下,将数字1235
强制转换为字符串'1235'
,它通过了验证就很好了。
现在,a FR open可以为Mongoose提供覆盖强制转换逻辑的功能(完全禁用或自定义),但是它是Open的,未实现。
另一种方法是更改整个铸造类型(allowed since 5.4),如下所示:
mongoose.Schema.Types.String.cast(false); // prevents all casts to string
...但是它可能很麻烦,因为对所有对象都应用相同的规则。