length: {maximum: 10} みたいなvalidatorを作る(is_a ActiveModel::EachValidator)
# Example # validates :email, email: true class EmailValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) fuzzy_valid_email_regexp = // record.errors.add(attribute, :invalid_email) unless fuzzy_valid_email_regexp =~ value end end
みたいなのは作ったことあったけど、任意の値を渡したくなるvalidatorを書くことがなかったので知らなかった。
UTF-8の文字列を扱ってるシステムなんだけど、深淵な理由からSJISにエンコードした時のbytesizeでvalidationしないといけないみたいな要件があり、調べた。特に特別にやらないといけないことはなかった。
# Example # validates :email, sjis_bytesize: {maximum: 100} class SjisBytesizeValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) sjis_bytesize = ほげほげ value if sjis_bytesize > options[:maximum] record.errors.add(attribute, :too_long, count: [:maximum]) end end end
みたいに options
を参照すれば良い。渡した値を事前に加工したりチェックしたければ initialize
でごにょごにょした後にsuper呼んどけば良い。
c.f.