如何验证此哈希参数? [英] How to validate this hash parameter?

查看:105
本文介绍了如何验证此哈希参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何为此散列参数编写正确的params验证:

How do I write the correct params validations for this hash parameter:

{
  "files": {
    "main.c": {
      "contents": "#include <stdio.h> ...",
      "foo": "bar"
    },
    "main.h": {
      "contents": "#define BLAH ...",
      "foo": "baz"
    },
    ... more files here ...
  }
}

files是我要验证的哈希参数. files的每个键都可以是任何内容(字符串);这些值是具有特定格式的哈希,该哈希也需要进行验证(需要contentsfoo).我正在使用葡萄0.9.0.

files is the hash parameter that I want to validate. Each key of files can be anything (a string); the values are hashes with a specific format that also needs to be validated (requires contents and foo). I'm using grape 0.9.0.

这就是我想要的:

params do
  optional :files, type: Hash do
    requires <any key>, type: Hash do
      requires :contents, type: String
      requires :foo, type: String
    end
  end
end

我已经阅读了文档,但我看不到如何实现这种验证.可能吗?我需要写一个自定义验证器吗?

I've read the documentation but I couldn't see how to achieve this kind of validation. Is it even possible? Do I need to write a custom validator?

一种替代方法是使用它:

An alternative is to have this instead:

{
  "files":
  [
    {
      "name":     "main.c",
      "contents": "#include <stdio.h> ...",
      "foo":      "bar"
    },
    {
      "name":     "main.h",
      "contents": "#define BLAH ...",
      "foo":      "baz"
    }
  ]
}

可以很容易地像这样验证:

which can be easily validated like this:

params do
  optional :files, type: Array do
    requires :name, type: String
    requires :contents, type: String
    requires :foo, type: String
  end
end

但是现在我失去了拥有唯一文件名的能力.

but now I lose the ability to have unique file names.

推荐答案

基于葡萄文档我会想到编写您自己的自定义验证器并选择第二种方法的想法.

Based on the grape documentation I would come up with the idea of writing your own custom validator and go with your second alternative.

class UniqueHashAttributes < Grape::Validations::Base
  def validate_param!(attr_name, params)
    # assuming @option is an array
    @option.each do |attribute|
      # detects if the value of the attribute is found more than once
      if params[attr_name].group_by { |h| h[attribute] }.values.collect(&:size).max > 1
        fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)],
             message: "must have only unique values for properties: '#{@option.join(', ')}'"
      end
    end
  end
end

还可以报告表示唯一性违规的自定义错误.当然,除了唯一性之外,该原理还可以用于执行不同类型的验证.

It would also be possible to report custom errors that present the uniqueness violations. Of course this principle can also be applied to perform different kind of validations than the uniqueness.

如果此验证器已加载到您的应用程序中,则可以在路由的params定义中使用它,如下所示:

If this validator is loaded in your application, you can utilize it in your params definition of the route as follows:

params do
  optional :files, unique_hash_attributes: [:name], type: Array do
    requires :name, type: String
    requires :contents, type: String
    requires :foo, type: String
  end
end
post '/validation' do
  'passed'
end

通过此实现,您还可以通过将:foo字段(或任何其他字段)添加到唯一的哈希属性数组中来将其指定为唯一.

With this implementation you could also specify the :foo field (or any other) to be unique by adding it to the array of the unique hash attributes.

对哈希值(名称,内容,foo)的任何验证在files验证器中保持不变,并且仍然适用.

Any validations of the Hash's values (name, contents, foo) remain unchanged of the files validator and still apply.

具有以下数据的邮寄请求将无法通过验证:

A post request with the following data would not pass the verification:

{   "files":
  [
    {
      "name":     "main.c",
      "contents": "#include <stdio.h> ...",
      "foo":      "bar"
    },
    {
      "name":     "main.c",
      "contents": "#define BLAH ...",
      "foo":      "baz"
    }
  ]
}

这篇关于如何验证此哈希参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆