You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

扩展apipie-rails的NumberValidator添加min/max校验时描述返回异常问题

问题根因
  • 你的description方法硬编码了范围校验提示,没有区分「非有效数字」和「数值超出范围」两种错误场景,所有校验失败都会返回自定义的范围提示
  • validate方法逻辑存在错误:配置min、max时,范围校验失败后没有正确返回false,会执行最后的true导致范围校验不生效;多余的self.class.validate(value)调用存在递归风险
  • 没有复用原生NumberValidator的错误描述,数值格式校验失败时需要返回原生校验器自带的提示
修正后代码
class NumberValidator < Apipie::Validator::BaseValidator
  def initialize(param_description, argument, options)
    super(param_description)
    @number_validator = Apipie::Validator::NumberValidator.new(param_description)
    @type = argument
    @options = options
    # 记录校验失败类型::invalid_number表示非有效数字,:out_of_range表示超出范围
    @validation_failed_type = nil
  end

  def validate(value)
    # 优先走原生数字格式校验
    unless @number_validator.valid?(value)
      @validation_failed_type = :invalid_number
      return false
    end

    # 未配置范围校验直接判定有效
    return true unless @options[:min] && @options[:max]

    # 范围校验
    unless value.to_i.between?(@options[:min], @options[:max])
      @validation_failed_type = :out_of_range
      return false
    end

    true
  end

  def self.build(param_description, argument, options, block)
    self.new(param_description, argument, options) if argument == :number
  end

  def description
    # 数字格式校验失败返回原生提示
    return @number_validator.description if @validation_failed_type == :invalid_number
    # 未配置范围时返回原生提示
    return @number_validator.description unless @options[:min] && @options[:max]
    # 范围校验失败返回自定义提示
    "Must be a number between #{@options[:min]} and #{@options[:max]}."
  end
end
实现说明
  • 新增实例变量记录校验失败的类型,作为返回不同错误描述的依据
  • 数值格式校验失败时,直接复用原生校验器的「Must be a number」提示
  • 仅当数值合法但超出min/max范围时,才返回自定义的范围提示
  • 兼容未配置min、max的场景,此时功能和原生NumberValidator完全一致

内容的提问来源于stack exchange,提问作者OwenH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 17:48:02