如何创建复用默认验证规则的自定义验证器以实现跨列跨模型复用?
实现可复用的百分比费用字段验证器
当然可以!你完全可以通过自定义ActiveModel::EachValidator封装这套重复的验证规则,让所有费用字段只用一行代码就能完成验证。
步骤1:创建自定义验证器
在app/validators/percent_fee_column_validator.rb文件中编写以下代码:
class PercentFeeColumnValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) # 处理必填验证 record.errors.add(attribute, :blank) if value.blank? # 处理格式验证 fee_regex = /^\d+(\.\d{1,2})?$/ # 替换为你实际使用的正则表达式 format_error_message = "格式错误,最多保留两位小数" # 替换为你的自定义错误提示 if value.present? && !value.to_s.match?(fee_regex) record.errors.add(attribute, format_error_message) end # 处理数值范围验证 if value.present? unless value.to_f.between?(0, 40) record.errors.add(attribute, "必须在0到40之间") end end end end
步骤2:在任意模型中调用验证器
现在不管哪个模型的费用字段,都能用一行代码复用这套规则:
# 示例模型1 class Order < ApplicationRecord validates :system_fee, percent_fee_column: true validates :system_discounted_fee, percent_fee_column: true end # 示例模型2 class Invoice < ApplicationRecord validates :service_fee, percent_fee_column: true end
可选:支持自定义规则参数
如果需要给个别字段调整验证规则(比如允许空值、修改数值范围),可以扩展验证器支持自定义选项:
# 扩展后的验证器 class PercentFeeColumnValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) # 允许关闭必填验证 presence_required = options.fetch(:presence, true) record.errors.add(attribute, :blank) if presence_required && value.blank? # 允许自定义格式规则 fee_regex = options[:format_regex] || /^\d+(\.\d{1,2})?$/ format_error_message = options[:format_message] || "格式错误,最多保留两位小数" if value.present? && !value.to_s.match?(fee_regex) record.errors.add(attribute, format_error_message) end # 允许自定义数值范围 min = options[:min] || 0 max = options[:max] || 40 if value.present? unless value.to_f.between?(min, max) record.errors.add(attribute, "必须在#{min}到#{max}之间") end end end end # 带自定义选项的使用示例 validates :optional_fee, percent_fee_column: { presence: false, max: 50 }
这样就把重复的验证逻辑完全封装,既实现了跨模型复用,又能根据需求灵活调整规则。
内容的提问来源于stack exchange,提问作者k0k0
相关产品推荐
相关产品推荐

