#カスタムバリデートでバリデーション前編
はじめに
前回の記事ではControllerでのバリデーションの具体例としてフォームオブジェクトを紹介しました。今回はモデルでのバリデーションとして、ロジックな検証をカスタムバリデートを用いてしていきます。
##カスタムバリデートとは
Railsに組み込まれているバリデーションだけでは足りない時、プロジェクト仕様のバリデーションルールを追加することになりますが、それを全てmodelに書くと可読性が悪くなります。管理も大変です。てな訳でバリデートクラスなるものを作って独自のルールをそこにまとめようということです。
##個別のEachValidator
カスタムバリデータを追加するには二つのアプローチがあります。
まずは個別の属性にバリデートをかけるEachValidator
について説明します。
今回はemailのバリデーションを例にします。emailがちゃんとemailの形式を取っているかのバリデーションです。
app/validtors/
階層に、カスタムバリデータクラスとして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
とクラスを名付ければ,モデルにて:~~
で呼び出せます。
つまり、下記のようになります。
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