Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

はじめに
前回の記事では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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした