Rails tips: カスタムバリデータクラスを作る(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

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を使用するのが最も簡単で便利です。

カスタムバリデータの規則

カスタムバリデータを書くときの規則は次のとおりです。

  1. バリデータを自動で読み込むときは、クラス名を名前Validator名前の部分はバリデータ名に置き換える)としなければならない。名前の末尾をValidatorにすることで、Railsはそのクラスをバリデータと認識できるようになる。
  2. バリデータクラスはActiveModel::EachValidatorクラスを継承しなければならない。
  3. #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をご自由にダウンロードいただけます。

関連記事

ActiveRecordで日付・時刻の範囲検索をシンプルに書く方法

ActiveRecordのRangeHandlerクラスとRubyの範囲メソッドRange#exclude_end?

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ