LoginSignup
13
4

More than 5 years have passed since last update.

カスタムバリデートでバリデーション前編 初心者→中級者へのSTEP3/25

Last updated at Posted at 2018-12-02

カスタムバリデートでバリデーション前編

はじめに
前回の記事ではControllerでのバリデーションの具体例としてフォームオブジェクトを紹介しました。今回はモデルでのバリデーションとして、ロジックな検証をカスタムバリデートを用いてしていきます。

カスタムバリデートとは

Railsに組み込まれているバリデーションだけでは足りない時、プロジェクト仕様のバリデーションルールを追加することになりますが、それを全てmodelに書くと可読性が悪くなります。管理も大変です。てな訳でバリデートクラスなるものを作って独自のルールをそこにまとめようということです。

個別のEachValidator

カスタムバリデータを追加するには二つのアプローチがあります。
まずは個別の属性にバリデートをかけるEachValidatorについて説明します。
今回はemailのバリデーションを例にします。emailがちゃんとemailの形式を取っているかのバリデーションです。

app/validtors/階層に、カスタムバリデータクラスとしてemail_validator.rbを作成します。

email_validator.rb
class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /\A[a-zA-Z0-9_\#!$%&`'*+\-{|}~^\/=?\.]+@[a-zA-Z0-9][a-zA-Z0-9\.-]+\z/
      record.errors[attribute] << (options[:message] || "はメールアドレスではありません")
    end
  end
end

個別の属性にバリデートをかけるカスタムバリデートを作成する場合、validate_eachを定義する必要があります。
validate_eachの引数、recordに呼び出し元のモデルインスタンスが入り、attributeに属性、valueに値が入ります。このメソッド内で呼び出し元のモデルインスタンスの属性値がemailとして正しい形式か検証しています。
ちなみに正規表現にて検証してますが、これにマッチしないとerrors[]にメッセージが格納されます。実はここの記述がないとエラー時にfalseを返してくれません。erros[]にエラーメッセージがあることで、そのデータは正しくないデータと判定します。

クラス名も重要です。~~Validatorとクラスを名付ければ,モデルにて:~~で呼び出せます。
つまり、下記のようになります。

User.rb
class User < ApplicationRecord
  validates :email, presence: true, email: true
end

これでemail属性にだけ先ほどカスタムバリデートクラスに記述した正規表現で検証できます。

まとめ

カスタムバリデートによる個別の属性の検証はこんな感じです。今回はルールがemailとして正しいかだけの検証だったのであまり差を感じませんが、もっと複雑なルールの場合、モデルにそれを書くよりこのカスタムバリデートクラスにまとめた方が、スッキリしていいですよね。
次回はもう一つのアプローチ、レコード一つ対象にバリデートをかけるものを説明してみます。

参考にしたの

Active Record バリデーション
https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF

【パーフェクトRails】バリデーションをクラスに分離する
https://waterlow2013.hatenablog.com/entry/2016/10/11/011312

メールアドレスの妥当性を正規表現でチェックする
http://rubytips86.hatenablog.com/entry/2014/03/28/135838

13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4