Active Record(Railsのモデル) バリデーションまとめ


Ruby on RailsのModelでのバリデーションはフォームなどで入力した値をシステムが許容できる値かをチェックするしくみです。バリデーションにより、DBに正しいデータを保存するように利用者をサポートします。

class Person < ActiveRecord::Base
validates :name, presence: true
end

Person.create(name: "John Doe").valid? # => true
Person.create(name: nil).valid? # => false

🤔 バリデーションの実行タイミング

createsaveupdateメソッドなどで呼び出した際にバリデーションチェックして、DBへの保存を行います。また、valid?メソッドを実行するとバリデーションを実行します。

🚜 主要なバリデーション

ここではRailsの所要なバリデーションを紹介します。

指定したカラムが空でないことをチェック

# presence で特定のカラムが空でないことをチェックします
validates :name, presence: true

# boolean(真偽値)では inclusion を使います
validates :finished, inclusion: { in: [true, false] }

DBのカラムにもnot null制約をつけましょう。

指定した値のどれかなことをチェック

# inclusion で指定した値のどれかなことをチェックします
validates :status, inclusion: { in: %w(draft publish private) }

指定したカラムがユニークであることをチェック

# uniqueness で1つのカラムの中でユニークなことをチェックします
validates :name, uniqueness: true

# 複数カラムでのユニーク制約をチェックする場合は、`scope`を設定します
validates :title, uniqueness: { scope: [:chapter] }

DBのテーブルにもユニーク制約をつけましょう。

指定したカラムの文字数のチェック

lengthで指定したカラムの文字数をチェックします。

# 値が「2文字以上」である
validates :name, length: { minimum: 2 }

# 値が「256文字以下」である
validates :name, length: { maximum: 256 }

# 値が「10文字以上、30文字以下」である
validates :name, length: { in: 10..30 }

DBのカラムにも長さの制限を付けることで、効率的にデータを格納できます。

正規表現で値をチェック

formatオプションを使うと、正規表現を使って指定した値をチェックできます。

メールアドレスのバリデーション

# 一般的なメールアドレスのフォーマットチェック
validates :email, format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }

URLのバリデーション

validates :url, format: /\A#{URI::regexp(%w(http https))}\z/

指定した数値であることをチェック

validates :age, numericality: true
オプション 説明
only_integer Integer(整数型)であることをチェック
greater_than 指定された値より大きいことをチェック
greater_than_or_equal_to 指定された値と等しい、あるいは大きいことをチェック
equal_to 指定された値と等しいことをチェック
less_than 指定された値よりも小さいことをチェック
less_than_or_equal_to 指定された値と等しい、あるいは小さいことをチェック

条件付きでバリデーションを行う

ifオプションを付けること、特定の条件のときだけバリデーションを行います。

validates :content, :presence if: :published?

def published?
status == 'published'
end

🐠 バリデーションのチェック結果を取得する

バリデーションvalid?か、保存メソッドsavecreateなどを実行して、バリデーションでエラーが出た場合はerrors[:attribute]にエラーの内容が保持されています。

class Person < ActiveRecord::Base
validates :name, presence: true, length: { minimum: 3 }
end

# nameがpersonオブジェクトに設定されていないためエラーを返す
person = Person.create

person.errors[:name]
# => ["空欄にはできません", "短すぎます (最小3文字)"]

person.errors.messages
# => {:name=>["空欄にはできません", "短すぎます (最小3文字)"]}

person.errors.full_messages
# => ['Nameは空欄にできません', 'Nameは短すぎます(最小3文字)']

🐡 バリデーションをスキップする

バリデーションを一時的に無視したい場合は次のように記述すると、バリデーションをスキップできます。

article.save!(validate: false)

🐮 オリジナルのバリデーションクラス:validates_with

validation_withを使うとバリデーション専用の別のクラスにレコードを渡すことができます。

# app/models/person.rb
class Person < ActiveRecord::Base
validates_with GoodnessValidator, field: %i[first_name last_name]
end
# app/models/validators/goodness_validator.rb
class GoodnessValidator < ActiveModel::Validator
def validate(record)
if options[:fields].any? { |field| record.send(field) == 'Evil' }
record.errors[:base] << 'これは悪人だ'
end
end
end

👽 参考リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍