为什么猫鼬验证器不验证字段类型?

时间:2020-04-18 09:36:16

标签: node.js mongoose mongoose-schema

我正在尝试验证猫鼬模式,但我无法理解一件事,即类型验证。我正在将数字类型传递给字符串字段,并期望它无法通过验证,但可以通过。这是怎么回事,任何人都可以解释一下这背后的逻辑吗?

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()


1 个答案:

答案 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

...但是它可能很麻烦,因为对所有对象都应用相同的规则。