带有参数的自定义验证器



我有以下类:

class PatientPaymentSpreadsheetRow < ApplicationSpreadsheetRow
include ActiveModel::Validations
validate :date_format
def date_format
unless value('Transaction').split('/').last.length == 4
errors.add('Transaction', 'date format invalid')
end
end
end

这种特殊的验证恰好作用于value('Transaction')。我希望我的验证器足够通用,可以传入任何值(例如value('Date of birth')(,并让它对该值进行操作。

我怎样才能做到这一点?

这是一个老问题,但我认为这更符合您的要求。

ActiveModel::EachValidator允许您将options作为散列传递,该散列将在具有options的类实例中可用。

你可以像一样在你的模型中设置验证

class SomeModel < ApplicationRecord
validates :transaction, date_format: { value: 'Transaction' }
end

自定义验证器看起来像:

class DateFormatValidator < ActiveModel::EachValidator
def validate_each(model, attribute, value)
return if options[:value].split('/').last.length == 4
#         ^^^^^^^ hash you pass is here
model.errors.add(attribute, 'date format invalid')
end
end

您可以编写自定义的"每个验证器",如指南:中所述

class DateFormatValidator < ActiveModel::EachValidator
def validate_each(model, attribute, value)
return if value.split('/').last.length == 4
model.errors.add(attribute, 'date format invalid')
end
end

并像这样使用:

class MyCustomModel
include ActiveModel::Validations
attr_accessor :my_date_attr
validates :my_date_attr, date_format: true
end

但可能您希望验证无条件运行,所以…

validate :date_format
DATES_TO_VALIDATE = ['Transaction', 'Date of birth', 'Other date']
def date_format
DATES_TO_VALIDATE.each do |key|
unless value(key).split('/').last.length == 4
errors.add(key, 'date format invalid')
end
end
end

根据Marek Lipka的回答,这可以提取为each_validator,每个模型都有一个自定义常数DATES_TO_VALIDATE,并在验证器中作为model.class::DATES_TO_VALIDATE访问它

相关内容

  • 没有找到相关文章

最新更新