【问题标题】:How to validate this hash parameter?如何验证此哈希参数?
【发布时间】:2015-02-27 23:14:30
【问题描述】:

如何为这个哈希参数编写正确的params 验证:

{
  "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。

这就是我想要的:

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

我已经阅读了documentation,但我不知道如何实现这种验证。甚至可能吗?我需要编写自定义验证器吗?


另一种方法是改为:

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

可以像这样轻松验证:

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

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

【问题讨论】:

  • 您阅读了哪些文档?你尝试过什么?
  • @vgoff 我读过these docs。我尝试过的唯一代码类似于我的问题中的第一个 ruby​​ 块,但它总是失败(即requires '*'requires /.*/,但我知道这些无论如何都行不通)。

标签: ruby grape grape-api


【解决方案1】:

基于grape documentation,我会想出编写您自己的自定义验证器的想法,然后选择您的第二个替代方案。

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

还可以报告存在唯一性违规的自定义错误。当然,除了唯一性之外,这个原则也可以应用于执行不同类型的验证。

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

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 字段(或任何其他字段)添加到唯一哈希属性的数组中来指定它是唯一的。

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

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

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

【讨论】:

    猜你喜欢
    • 2018-09-03
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 2020-04-23
    • 2014-12-30
    • 2012-11-04
    相关资源
    最近更新 更多