Railsにおけるバリデーション(validation)

今回はRailsにおけるバリデーション(検証)について見ていきましょう。 バリデーションはモデル(Model)についた機能であり、ユーザーから渡されたデータをDBに保存する時に必ず実施される重要なステップです。

テーブルのレコードを作成・更新する時、「フォームから送られた値を調べ、値の形式や範囲が間違っていたら妥当なエラーを出す」という処理を必ず行います。これがバリデーションです。

たとえばモデルオブジェクトのsaveメソッドを呼び出すと、saveメソッドはバリデーションを実行します。データが妥当であればDBに格納されますが、そうでなければfalseが返ってきます。ちなみにcreateメソッド、updateメソッドもデータが妥当でなければ、falseを返します。

バリデーションを設定するには、モデルクラス内でvalidatesメソッドが定義されている必要があります。次からvalidatesメソッドの書き方について見ていきましょう。

validatesメソッドの書き方

validatesメソッドの引数には、シンボルでモデルの属性名を指定し、後に「バリデーションの種類: true」を並べることで指定した種類の値の検証が行われます。

class User < ApplicationRecord
  validates :name, :address, presence: true
end

ちなみに次のように
「バリデーションの種類: {オプション: オプションの値}」とすると文字数の検証などオプションを追加できます。

class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }
end

バリデーションの数々

# 空でないこと
validates :title, presence: true

# 空であること
validates :login, absence: true

# 一意性(ユニーク)
validates :user_name, uniqueness: true

# 長さ
validates :title,    length: { minimum: 1 }       # 「1文字以上」
validates :title,    length: { maximum: 75 }      # 「75文字以下」
validates :title,    length: { in: 1..75 }        # 「1文字以上75文字以下」
validates :password, length: { is: 8 }            # 「8文字のみ」

# メールアドレス
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, uniqueness: true, format: { with: VALID_EMAIL_REGEX }

# 数値
validates :age, numericality: true

最後の「numericality」ですが、便利なオプションが多数用意されています。

オプション 概要
only_integer 整数のみ
greater_than 指定された値よりも大きいか
greater_than_or_equal_to 指定された値と等しい、あるいは大きいか
equal_to 指定された値と等しいか
less_than 指定された値よりも小さいか
less_than_or_equal_to 指定された値と等しいか、あるいは小さいか
odd trueに設定した場合、奇数か
even trueに設定した場合、偶数か

例えば以下では、

●整数のみ
●1以上100未満

という検証条件を指定しています。

class User < ApplicationRecord
  validates :number, presence: true,
      numericality: {
          only_integer: true,
          greater_than: 0,
          less_then: 100,
          allow_blank: true
      },
      uniqueness: true
end

バリデーションの動作検証の仕方

実際にどうバリデーションが動いているかは、railsコンソールを動かして判断することができます。

$ rails console
>> User.create(name: "Michael Hartl", email: "mhartl@example.com",
?>             password: "foobar", password_confirmation: "foobar")
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com",
created_at: "2016-05-23 20:36:46", updated_at: "2016-05-23 20:36:46",

オブジェクト別のエラーを見るときは「errors.messages」を使って次のようにします。

$ rails console
>> User.errors.messages
=> {User=> ["can't be blank"]}