概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Ruby on Rails / Validations - build your own custom validator
- 原文公開日: 2018/01/11
- 著者: Paweł Dąbrowsk
Rails tips: カスタムバリデータクラスを作る(翻訳)
Railsに組み込まれているバリデータだけでは足りなくなると、独自のバリデーションルールを書かなければならなくなります。これをやりだすとモデルがたちまち肥大化してしまうので、これを避けるにはバリデーションロジックを別クラスに切り出すのが一番です。これによってコードがすっきりと分離され、再利用しやすくなります。
モデルのバリデーション
バリデーションコードを切り離す方法をご覧いただくために、モデルのクラスをサンプルとして1つ作成し、まずはそこに単純なバリデーションルールを記述します。
class User < ActiveRecord::Base
PHONE_REGEX = /some_regex/
validates :phone, format: { with: PHONE_REGEX, message: 'invalid phone number' }
end
バリデーションルールは正しくすっきりと書かれていますが、このままでは再利用できません。こんなときはバリデータクラスの作成を検討すべきです。公式ドキュメントをあさって該当部分を見つけます。
個別の属性を検証するためのカスタムバリデータを追加するには、
ActiveModel::EachValidator
を使用するのが最も簡単で便利です。
カスタムバリデータの規則
カスタムバリデータを書くときの規則は次のとおりです。
- バリデータを自動で読み込むときは、クラス名を
名前Validator
(名前
の部分はバリデータ名に置き換える)としなければならない。名前の末尾をValidator
にすることで、Railsはそのクラスをバリデータと認識できるようになる。 - バリデータクラスは
ActiveModel::EachValidator
クラスを継承しなければならない。 #validate_each
メソッドを実装しなければならない。
カスタムバリデータ
上の規則を守って、最初のカスタムバリデータを作成してみましょう。
class PhoneFormatValidator < ActiveModel::EachValidator
PHONE_REGEX = /some_regex/
def validate_each(record, attribute, value)
if value.match(PHONE_REGEX).blank?
record.errors.add(attribute, 'invalid phone number')
end
end
end
カスタムバリデータをRailsのモデルで使う
上で作成したカスタムバリデータで現在のロジックを置き換えます。必要な作業は、バリデータの名前(phone_format
)を指定することだけです。
class User < ActiveRecord::Base
validates :phone, phone_format: true
end
バリデータクラスを作成したらテストを書くこともお忘れなく。
Railsアプリのリファクタリングでお困りの方へ
知りたいことがありましたら、twitterまたはフォームにてお気軽にお問い合わせください。
コードを正しくテストするには
コードを正しくテストするのは何かと困難であり、しかも最も大変なのはテストを書き始めるときです。テストを書き始めるときに役立つRSpec & Test Driven Developmentの無料ebookをご自由にダウンロードいただけます。