首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >干验证:不区分大小写的`included_in?`验证与Dry::Validation.Schema

干验证:不区分大小写的`included_in?`验证与Dry::Validation.Schema
EN

Stack Overflow用户
提问于 2018-11-19 18:18:37
回答 1查看 445关注 0票数 1

作为ETL管道的一部分,我试图为预先确定的有效品牌列表创建一个验证。我的验证要求不区分大小写,因为有些品牌是不重要的复合词或缩写。

我创建了一个自定义谓词,但我不知道如何生成适当的错误消息。

我读过错误消息文档,但很难解释:

  • 如何为我的自定义谓词构建语法?
  • 我是否可以直接应用模式类中的消息,而不引用外部.yml文件?我看起来像这里,这似乎没有我所希望的那么简单。

下面我给出的代码表示了我尝试使用的内置谓词和自定义谓词,每个谓词都有各自的问题。如果有更好的方法来组成一个达到同样目标的规则,我很乐意学习它。

代码语言:javascript
复制
require 'dry/validation'

CaseSensitiveSchema = Dry::Validation.Schema do
  BRANDS = %w(several hundred valid brands)

  # :included_in? from https://dry-rb.org/gems/dry-validation/basics/built-in-predicates/
  required(:brand).value(included_in?: BRANDS)
end

CaseInsensitiveSchema = Dry::Validation.Schema do
  BRANDS = %w(several hundred valid brands)

  configure do
    def in_brand_list?(value)
      BRANDS.include? value.downcase
    end
  end

  required(:brand).value(:in_brand_list?)
end


# A valid string if case insensitive
valid_product = {brand: 'Valid'}

CaseSensitiveSchema.call(valid_product).errors
# => {:brand=>["must be one of: here, are, some, valid, brands"]} # This message will be ridiculous when the full brand list is applied

CaseInsensitiveSchema.call(valid_product).errors
# => {}   # Good!



invalid_product = {brand: 'Junk'}

CaseSensitiveSchema.call(invalid_product).errors
# => {:brand=>["must be one of: several, hundred, valid, brands"]}  # Good... (Except this error message will contain the entire brand list!!!)

CaseInsensitiveSchema.call(invalid_product).errors
# => Dry::Validation::MissingMessageError: message for in_brand_list? was not found
# => from .. /gems/2.5.0/gems/dry-validation-0.12.2/lib/dry/validation/message_compiler.rb:116:in `visit_predicate'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-19 21:50:15

引用我的错误消息的正确方法是引用谓词方法。不需要担心argvalue等。

代码语言:javascript
复制
en:
  errors:
    in_brand_list?: "must be in the master brands list"

此外,通过这样做,我能够在没有单独的.yml的情况下加载此错误消息:

代码语言:javascript
复制
CaseInsensitiveSchema = Dry::Validation.Schema do
  BRANDS = %w(several hundred valid brands)

  configure do
    def in_brand_list?(value)
      BRANDS.include? value.downcase
    end

    def self.messages
      super.merge({en: {errors: {in_brand_list?: "must be in the master brand list"}}})
    end     
  end

  required(:brand).value(:in_brand_list?)
end

我仍然希望看到其他实现,特别是泛型不区分大小写的谓词。很多人说dry-rb组织得很好,但我觉得很难理解。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53380501

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档