ruby 如何使用dry-schema gem验证不同对象的数组

ndasle7k  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(80)

假设我有这样一个JSON对象,它有一个包含各种对象的数组,比如:

{
  "array": [
    {
      "type": "type_1",
      "value": 5
    },
    {
      "type": "type_2",
      "kind": "person"
    }
  ]
}

根据JSON模式验证,我可以使用以下JSOM模式定义来验证此模式:

{
  "type": "object",
  "properties": {
    "array": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "type_1"
                ]
              },
              "value": {
                "type": "integer",
                "enum": [
                  5
                ]
              }
            }
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "type_2"
                ]
              },
              "kind": {
                "type": "string",
                "enum": [
                  "person"
                ]
              }
            }
          }
        ]
      }
    }
  }
}

如何使用dry-schema gem验证输入JSON?你有什么想法吗?

5jvtdoz2

5jvtdoz21#

要解决这个问题,请尝试以下代码:

class TestContract < Dry::Validation::Contract
  FirstHashSchema = Dry::Schema.Params do
    required(:type).filled(:string)
    required(:value).filled(:integer)
  end

  SecondHashSchema = Dry::Schema.Params do
    required(:type).filled(:string)
    required(:kind).filled(:string)
  end

  params do
    required(:array).array do
      # FirstHashSchema.or(SecondHashSchema) also works
      schema FirstHashSchema | SecondHashSchema
    end
  end
end

valid_input = {
  array: [
    {
      type: 'type_1',
      value: 5
    },
    {
      type: 'type_2',
      kind: 'person'
    }
  ]
}

TestContract.new.call(valid_input) #=> Dry::Validation::Result{:array=>[...] errors={}}

invalid_input = {
  array: [
    {
      type: 'type_1',
      bad_key: 5
    },
    {
      type: 'type_2',
      kind: 'person'
    }
  ]
}

TestContract.new.call(invalid_input) #=> Dry::Validation::Result{:array=>[...] errors={:array=>{0=>{:or=>[...]}}}

这里的关键是方法#schemaDocumentation

相关问题