【问题标题】:dry-struct How to conditionally validate one attribute?dry-struct 如何有条件地验证一个属性?
【发布时间】:2018-11-12 20:54:30
【问题描述】:

我正在使用干类型和干结构,我想进行条件验证。

班级:

class Tax < Dry::Struct
  attribute :tax_type, Types::String.constrained(min_size: 2, max_size: 3, included_in: %w[IVA IS NS])
  attribute :tax_country_region, Types::String.constrained(max_size: 5)
  attribute :tax_code, Types::String.constrained(max_size: 10)
  attribute :description, Types::String.constrained(max_size: 255)
  attribute :tax_percentage, Types::Integer
  attribute :tax_ammount, Types::Integer.optional
end

我想将tax_ammount 验证为整数和强制if `tax_type == 'IS'。

【问题讨论】:

    标签: ruby dry-rb dry-types dry-struct


    【解决方案1】:

    dry-struct 真正用于基本类型断言和强制。

    如果您想要更复杂的验证,那么您可能还想实现dry-validation(正如dry-rb 推荐的那样)

    查看Validating data with dry-struct 哪些状态

    请不要。结构体旨在与有效输入一起工作,它无法生成足以向用户显示它们的错误消息等。使用干验证来验证传入数据,然后将其输出传递给结构体。

    使用dry-validation 的条件验证类似于

    TaxValidation = Dry::Validation.Schema do
    
      # Could be:
      #   required(:tax_type).filled(:str?, 
      #      size?: 2..3, 
      #      included_in?: %w(IVA IS NS)) 
      # but since we are validating against a list of Strings I figured the rest was implied
      required(:tax_type).filled(included_in?: %w(IVA IS NS)) 
      optional(:tax_amount).maybe(:int?)
    
      # rule name is of your choosing and will be used 
      # as the errors key (i just chose `tax_amount` for consistency)
      rule(tax_amount:[:tax_type, :tax_amount]) do |tax_type, tax_amount|
        tax_type.eql?('IS').then(tax_amount.filled?) 
      end
    end
    
    • 这要求tax_type%w(IVA IS NS) 列表中;
    • 允许tax_amount 是可选的,但如果填写它必须是Integer (int?) 和;
    • 如果tax_type == 'IS' (eql?('IS')) 则必须填写tax_amount(这意味着根据上述规则,它必须是Integer)。

    显然,您也可以验证您的其他输入,但为了简洁起见,我省略了这些。

    例子:

    TaxValidation.({}).success?
    #=> false
    TaxValidation.({}).errors
    # => {:tax_type=>["is missing"]}
    TaxValidation.({tax_type: 'NO'}).errors
    #=>  {:tax_type=>["must be one of: IVA, IS, NS"]}
    TaxValidation.({tax_type: 'NS'}).errors
    #=>  {}
    TaxValidation.({tax_type: 'IS'}).errors
    #=> {:tax_amount=>["must be filled"]}
    TaxValidation.({tax_type: 'IS',tax_amount:'NO'}).errors
    #=> {:tax_amount=>["must be an integer"]}
    TaxValidation.({tax_type: 'NS',tax_amount:12}).errors 
    #=> {}
    TaxValidation.({tax_type: 'NS',tax_amount:12}).success?
    #=> true 
    

    【讨论】:

    • 即使知道干结构并不意味着用作验证器,对于大多数情况下(数据库和 XML 之间的数据映射)来说,它是完美的,因为它简单而有效。对于更复杂的情况,您的建议可以正常工作,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 2013-04-13
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多