1

私のアプリケーションには、app/validators に保持してから複数のモデルを呼び出す複数のカスタム バリデーターがあります。

ほとんどの場合、正規表現ベースの検証、電子メール、携帯電話など、基本的に特定の形式にする必要があるカスタム データ文字列に対してこれを行います。

例えば:

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
      record.errors[attribute] << (options[:message] || "is not a valid email format")
    end
  end
end

class IpValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/
      record.errors[attribute] << (options[:message] || "is not a valid IP format")
    end
  end
end

この方法の欠点は、大規模なアプリケーションでは煩わしくなる可能性がある、ほとんど同じコードを含む余分なファイルがたくさんあることです。

モデル間で再利用できるように正規表現ベースの検証を定義するより良い方法 (より DRY) はありますか?

4

1 に答える 1

2

正規表現検証用の基本クラスを作成できます。

class RegexValidator < ActiveModel::EachValidator
  def regex_validate_each(regex, err_msg, record, attribute, value)
    unless value =~ regex
      record.errors[attribute] << (options[:message] || err_msg)
    end
  end
end

次に、次のようにサブクラス化します。

class EmailValidator < RegexValidator
  def validate_each(record, attribute, value)
    regex_validate_each(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, "is not a valid IP format", record, attribute, value)
  end
end
于 2012-11-19T09:56:20.613 に答える