【问题标题】:Joi.forbidden() equivalent in Mongoose猫鼬中的 Joi.forbidden() 等效项
【发布时间】:2020-04-15 21:17:45
【问题描述】:

如果value 设置为option1,则下面的架构允许我拥有所需的optionalField,但如果值设置为option2,则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,则验证将失败,除非 value 是 option1。

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

谢谢!

【问题讨论】:

    标签: node.js mongodb validation mongoose joi


    【解决方案1】:

    你可以像这样使用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
    }
    

    【讨论】:

    • 谢谢!我最终使用了非常相似的东西:optionalField: { type: Number, required: function() { return this.value === 'option1' }, validate(optionalField) { if (this.value !== 'option1') { if (optionalField) throw new Error() } } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 2019-03-20
    • 1970-01-01
    • 2018-10-31
    • 2018-11-29
    • 2020-10-16
    相关资源
    最近更新 更多