node.js - Mongoose 中的 Joi.forbidden() 等效项

标签 node.js mongodb validation mongoose joi

如果 value 设置为 option1 但如果 value 设置为 option2,则以下架构允许我拥有所需的 optionalField 那么 optionalField 可以设置为用户想要的任何内容。相反,如果 value 设置为 option1 以外的任何值并且传入 optionalField ,我希望验证失败。

const validValues = ['option1', 'option2']

const sampleSchema = new mongoose.Schema({
    value: {
        type: String,
        enum: validValues,
        required: true
    }   

    optionalField: {
        type: Number,
        required: function() { return this.value === 'option1' }
        // validation should fail if this property is passed in when value is anything but option1
    }
})

Joi 有一个很好的方法来实现这一点,使用 Joi.forbidden():

const validValues = ['option1', 'option2']

const schema = Joi.object({
    value: Joi.string().valid(...validValues).required(),
    optionalField: Joi.string().when('value', { is: 'option1', then: Joi.required() otherwise: Joi.forbidden() })
})

如果我使用此架构进行验证并将 optionalField 传递给 Joi,则验证将失败,除非 valueoption1

我希望找到一种方法在 Mongoose 中实现同样的目标。

谢谢!

最佳答案

您可以使用custom validators像这样:

  optionalField: {
    type: Number,
    required: function() {
      return this.value === "option1";
    },
    validate: {
      validator: function(v) {
        console.log({ v });
        return !(this.value !== "option1" && v.toString());
      },
      message: props =>
        `${props.value} optionalField is forbidden when value is not option1`
    }
  }

示例路线:

router.post("/sample", (req, res) => {
  const sample = new Sample(req.body);

  sample
    .save()
    .then(doc => res.send(doc))
    .catch(err => res.status(500).send(err));
});

输入1:

{
    "value": "option2",
    "optionalField": 11
}

结果 1:(错误)

{
    "errors": {
        "optionalField": {
            "message": "11 optionalField is forbidden when value is not option1",
            "name": "ValidatorError",
            "properties": {
                "message": "11 optionalField is forbidden when value is not option1",
                "type": "user defined",
                "path": "optionalField",
                "value": 11
            },
            "kind": "user defined",
            "path": "optionalField",
            "value": 11
        }
    },
    "_message": "Sample validation failed",
    "message": "Sample validation failed: optionalField: 11 optionalField is forbidden when value is not option1",
    "name": "ValidationError"
}

输入2:

{
    "value": "option2"
}

结果2:(成功)

{
    "_id": "5e031b473cbc432dfc03fa0e",
    "value": "option2",
    "__v": 0
}

输入3:

{
    "value": "option1"
}

结果 3:(错误)

{
    "errors": {
        "optionalField": {
            "message": "Path `optionalField` is required.",
            "name": "ValidatorError",
            "properties": {
                "message": "Path `optionalField` is required.",
                "type": "required",
                "path": "optionalField"
            },
            "kind": "required",
            "path": "optionalField"
        }
    },
    "_message": "Sample validation failed",
    "message": "Sample validation failed: optionalField: Path `optionalField` is required.",
    "name": "ValidationError"
}

输入4:

{
    "value": "option1",
    "optionalField": 11
}

结果4:(成功)

{
    "_id": "5e031ba83cbc432dfc03fa10",
    "value": "option1",
    "optionalField": 11,
    "__v": 0
}

关于node.js - Mongoose 中的 Joi.forbidden() 等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59474717/

相关文章:

php - Node 服务器屏幕截图 无法在实时 ubuntu 服务器上工作

MongoDB shell 历史不记得 'authentications'

mongodb - 如何反转展开聚合?

regex - 电子邮件验证 - @ 之前和点之前的字符长度

asp.net-mvc - 属性级验证错误阻碍了类级验证的验证

node.js - 使用 NodeJs 上传文件

css - Node 找不到导入整齐

python - 使用 Node.js/python 的生产者/消费者 + Worker 架构

javascript - 使用其他电话验证插件进行电话验证

php - - mongodb/mongodb 1.2.0 需要 ext-mongodb ^1.3.0 -> 您的系统中缺少请求的 PHP 扩展 mongodb