今回取り上げるのは、Active RecordとActive Modelを使ったバリデーション機能の実装です。
Webアプリケーションでユーザが入力されたデータが正しい形式であるかを確かめるには、バリデーションチェックを行います。
またデータに誤りがあれば、それをユーザに伝えて再度値を入力し直してもらう必要があります。
データベースの制約を用いる方法もありますが、Railsのモデルを用いることでデータに関するエラーをアプリケーション層でまとめて処理できるようになります。
オンラインでプログラミング学習を始めてみたいなら、米国シリコンバレー発祥の世界最大級のオンライン学習プラットフォーム、Udemyがおすすめです。
こちらの記事で紹介するフレームワーク、Ruby on Railsも学ぶことができます!
よくわかるRuby on Rails入門 オンライン講座
バリデーションとは

バリデーションは、アプリケーション中でデータベースにレコードを登録する際や更新する際に、そのデータが正しい形式であるのかどうかを検証する機能です。
アプリケーション中でデータベースのレコードを扱う際には、データの形式に制限を設けたい場合がほとんどです。
そういった場合、バリデーションを設定しておくことで値を自動的に検証し、値が適切でないときにはエラーメッセージをユーザに対して表示することができます。
今回はイベントを管理するサンプルアプリケーション上にバリデーションを実装していきます。
同じ環境で試してみたい方は、以下に従ってコマンドを実行しておいてください。
# 新規プロジェクトの作成
$ rails new event-app
$ cd event-app
# scaffoldコマンドで各種モデルの関連ファイルを自動生成
$ rails generate scaffold event name:string hold_date:date
$ rails generate scaffold user name:string email:string password:string
# データベースの作成
$ rails db:create
# マイグレーションの実行
$ rails db:migrate
現場を意識した本格的な学習カリキュラムで、本物のスキルを身につけたいならこちら!
困ったときにいつでも相談できるバディ制度でわからないこともすぐに解決できます。
プログラミングスクールといえば【RUNTEQ】
バリデーションの設定方法
基本的なバリデーションの設定は以下のようにActiveRecordオブジェクト内に記述します。
必要な情報は、バリデーションをかけたいカラム名と制約の内容です。
class Event < ApplicationRecord
validates :name, presence: true
end
これは、Eventモデルのnameというカラムがnil(空)でないようにしたいときのバリデーションです。
presenceは「存在すること」という意味です。
では、この時にnameを空にしてデータを登録しようとした場合、どうなるか試してみましょう。
$ rails console
irb(main):001:0> event = Event.new
(0.9ms) SELECT sqlite_version(*)
=> #<Event:0x000002b12fb3c170 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil>
irb(main):002:0> event.name = ''
=> ""
irb(main):003:0> event.hold_date = Time.parse('20220101')
=> 2022-01-01 00:00:00 +0900
irb(main):004:0> event.save
=> false
falseが返されましたので、バリデーションが機能しているようです。
どのようなバリデーションに引っ掛かってしまったのかを確認してみます。
irb(main):005:0> event.errors.full_messages
=> ["Name can't be blank"]
Nameカラムが空であることを指摘されていますね。
正しくバリデーションがかかっていることが確認できました。
全てのバリデーションチェックを通過した場合、trueが返され保存に成功します。
バリデーションのチェックのみを行い、データの保存などはしてほしくないときには、vaild?メソッドを使います。
irb(main):006:0> event.name = 'sample event'
=> "sample event"
irb(main):007:0> event.valid?
=> true
irb(main):008:0> event.save
TRANSACTION (0.1ms) begin transaction
Event Create (1.5ms) INSERT INTO "events" ("name", "hold_date", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "sample event"], ["hold_date", "2022-01-01"], ["created_at", "2021-11-07 06:23:04.564754"], ["updated_at", "2021-11-07 06:23:04.564754"]]
TRANSACTION (3.4ms) commit transaction
=> true
また、データベースの制約も同時に行った方がシステムが安定しますので、一般的には2重チェックを行ったりします。
エクスクラメーション(!)付きメソッド

ActiveRecordにはエクスクラメーション(!)の付いたメソッドが存在します。
保存操作を行う、createメソッド、saveメソッド、updateメソッドなどです。
エクスクラメーションが付いたものとついていないものが存在し、それぞれ動作が違います。
エクスクラメーションの付いていないメソッドは、バリデーション失敗時にfalseを返すだけです。
一方エクスクラメーションの付いたメソッドは、バリデーション失敗時に例外を返します。
$ rails console
irb(main):001:0> event = Event.new
(0.8ms) SELECT sqlite_version(*)
=> #<Event:0x000002b5c0afe628 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil>
irb(main):002:0> event.name = ''
=> ""
irb(main):003:0> event.hold_date = Time.parse('20230101')
=> 2023-01-01 00:00:00 +0900
irb(main):004:0> event.save
=> false
irb(main):006:0> event.save!
C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/activerecord-6.1.4.1/lib/active_record/validations.rb:80:in `raise_validation_error': Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)
saveメソッドでバリデーションエラーが発生した場合はfalseを返しています。
しかし、save!メソッドでバリデーションエラーが発生した場合は例外を発生させていることがわかります。
これらは用途に応じて使い分けましょう。
エクスクラメーション付きのメソッドは開発時の動作確認などにも使えますので、ぜひ覚えておきましょう。
各種バリデーション
様々な種類のバリデーションについて見ていきます。
また、ひとつのデータに対してバリデーションは複数指定することができます。
空白バリデーション
presenceルールでは、データがnilでないことを検証します。
必ずデータが存在してほしい場合に使います。
absenceルールでは、データがnilであることを検証します。
データが存在してほしくない場合に使います。
また、allow_blankは明示的にnilを許可する共通オプションです。
別のバリデーションによってnilが禁止されたときにそれを解除するために使います。
class Event < ApplicationRecord
validates :name, presence: true
# validates :name, absence: true
# validates :name, allow_blank: true
end
チェックボックスのバリデーション
acceptanceルールでは、チェックボックスがオンになっていることを検証します。
利用規約に同意を求めたい場合などに用います。
class Event < ApplicationRecord
validates :name, acceptance: true
end
確認項目のバリデーション
confirmationルールでは、2つのテキストフィールドの値が一致するかを検証します。
メールアドレスやパスワードの確認用フォームに使用します。
一致するかの検証は確認用フィールドがnilではない場合にのみおこなわれるため、空白チェックと併用することが多いです。
case_sensitiveオプションにより大文字小文字を区別するかを指定することもできます(デフォルトはtrue)。
class User < ApplicationRecord
validates :password, confirmation: true
validates :password_confirmation, presence: true
validates :email, confirmation: { case_sensitive: false }
validates :email_confirmation, presence: true
end
また、ビュー側には通常のフォームフィールドと_confirmationを付け加えたフィールドを用意します。
<%= text_field :person, :email %>
<%= text_field :person, :email_confirmation %>
文字数のバリデーション
lengthルールでは、データの文字数による検証を行います。
minimumあるいはmaximumでは、文字数の下限や上限を指定できます。
inでは、文字数の範囲を指定できます(minimumとmaximum両方を設定した動作と同じ)。
isでは、指定した文字数とぴったり同じであるかを検証します。
class Event < ApplicationRecord
validates :name, length: { minimum: 5 }
# validates :name, length: { maximum: 20 }
# validates :name, length: { minimum: 5, maximum: 20 }
# validates :name, length: { in: 5..20 }
# validates :name, length: { is: 10 }
end
重複のバリデーション
uniquenessルールでは、一意性の検証を行います。
データベースに既に重複するデータが存在する場合はfalseを返します。
case_sensitiveオプションにより大文字小文字を区別するかを指定することもできます(デフォルトはtrue)。
class Event < ApplicationRecord
validates :name, uniqueness: true
validates :name, uniqueness: { case_sensitive: false }
end
数値のバリデーション
numericalityルールでは、値が数値であるかを検証します。
デフォルトではnilが許容されていないため、入力が任意のカラムである場合には明示的にallow_blankをtrueにする必要があります。
class Event < ApplicationRecord
validates :capacity, numericality: true
end
numericalityルールでは以下のようなオプションが使えます。
only_integerオプションは数値の中でも整数値であるかを検証します。
greater_than、greater_than_or_equal_toオプションはそれぞれ指定値より大きい、指定値以上であるかを検証します。
equal_toオプションは指定値と一致するかを検証します。
less_than、less_than_or_equal_toオプションはそれぞれ指定値未満、指定値以下であるかを検証します。
odd、evenオプションはそれぞれ奇数、偶数であるかを検証します。
class Event < ApplicationRecord
validates :capacity, numericality: { only_integer: true }
# validates :capacity, numericality: { greater_than: 100 }
# validates :capacity, numericality: { greater_than_or_equal_to: 100 }
# validates :capacity, numericality: { equal_to: 1000 }
# validates :capacity, numericality: { less_than_or_equal_to: 20000 }
# validates :capacity, numericality: { less_than: 20000 }
# validates :capacity, numericality: { odd: true }
# validates :capacity, numericality: { even: true }
end
フォーマットバリデーション
formatルールでは、正規表現にマッチするかを検証します。
class Event < ApplicationRecord
validates :name, format: { with: /\A[a-zA-Z]+\z/ }
end
値を含む・含まないのバリデーション
inclusionルールでは、入力値が指定した値の中に含まれているかを検証します。
exclusionルールでは、入力値が指定した値の中に含まれていないかを検証します。
セレクトボックスなどで不正な値が送信されていないかを検証するなどの目的で使用します。
class Event < ApplicationRecord
validates :status, inclusion: { in: %w(archive, in_session, scheduled) }
validates :phase, exclusion: { in: %w(cancel, rehearsal) }
end
プログラミングでわからないことがあったら、その道のプロに質問するのが一番!
現役で活躍中のエンジニアと繋がって、効率的にWeb開発のスキルを身につけましょう。
プログラミング学習のスキルプラットフォーム【MENTA】
エラーメッセージについて

バリデーションでエラーが発生した場合、画面上にその内容を表示してユーザに伝えたいという場合がほとんどです。
Railsではバリデーションが行われた後にエラーがあった場合は、それらをmodel.errorsに格納します。
注意する点として、バリデーションを行っていない状態ではエラーは存在しません。
明示的にエラーを取得したい場合には、valid?メソッドなどによりバリデーションを実行後にerrorsを参照します。
エラーメッセージの変更
デフォルトのエラーメッセージを変更したい場合は、message共通オプションを用います。
class Event < ApplicationRecord
validates :name, presence: { message: "イベント名を入力してください。" }
end
messageオプション内では以下の変数が利用可能で、メッセージを表示する際にそれぞれ動的に変化します
valueはユーザがフィールドに入力した値に置き換えられます。
model、attributeはそれぞれモデル名、カラム名に置き換えられます。
countはmaximumやminimumなどの特定のオプションで指定された数値に置き換えられます。
class Event < ApplicationRecord
validates :name, nuiqueness: { message: "%{value}はすでに使われています。" }
end
エラーメッセージの表示
バリデーションエラーのコレクションはerrors.messagesで取得できます。
また、エラーの全文はerrors.full_messagesで取得できます。
$ rails console
irb(main):001:0> event = Event.new
(1.5ms) SELECT sqlite_version(*)
=> #<Event:0x0000021f337d8fd0 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil>
irb(main):002:0> event.valid?
=> false
irb(main):003:0> event.errors.messages
=> {:name=>["can't be blank"]}
irb(main):004:0> event.errors.full_messages
=> ["Name can't be blank"]
以下は実際にアプリケーションでよく使う例です。
ビュー側でユーザに対してエラーメッセージを表示したいときに使います。
errors.any?の部分でエラーがあるかをチェックし、エラーがあった場合にはerrors.full_messagesで全エラー文を取得しています。
<% if model.errors.any? %>
<ul>
<% model.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
上のようなエラーメッセージを表示するパーシャル(部分的に再利用できるテンプレート)を作成しておき、以下のようにレンダリングしたりします。
この例では、layouts/errors.html.erbにエラー表示用のテンプレートを用意しています。
<%= form_for(@event) do |f|%>
<%= render 'layouts/errors', model: f.object %>
また、特定のフォームフィールドに対するエラー文のみを取得することもできます。
各入力フォームの真下や真上にエラーメッセージを表示したい場合などに使います。
<% if event.errors.include?(:name) %>
<p><%= event.errors.full_messages_for(:name).first %></p>
<% end %>
エラーメッセージの日本語化
エラーメッセージを日本語に対応させるには、i18nのパッケージを使用します。
ちなみにi18nとは国際化を意味する英単語である「internationalization」を省略したものです。
18とはiとnの間に18個のアルファベットがあることを意味しています。
Gemfileに以下のrails-i18nを追加し、パッケージをインストールします。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.2'
gem 'rails-i18n'
...
$ bundle install
次にconfig/application.rbの設定を書き換え、使用するロケール(言語)をjaに変更します。
...
module EventApp
class Application < Rails::Application
config.load_defaults 6.1
config.i18n.default_locale = :ja # この行を追加
end
end
さらにconfig/localesフォルダの中にja.ymlを作成し、以下のようにしてカラム名を記述します。
ja:
activerecord:
attributes:
event:
name: "イベント名"
hold_date: "開催日"
これでエラーメッセージが日本語化できました。
実際に日本語になっていることを確認してみましょう。
$ rails console
irb(main):001:0> event = Event.new
(1.0ms) SELECT sqlite_version(*)
=> #<Event:0x0000013bf42aac48 id: nil, name: nil, hold_date: nil, created_at: nil, updated_at: nil>
irb(main):002:0> event.valid?
=> false
irb(main):003:0> event.errors.full_messages
=> ["イベント名を入力してください"]
しっかりと日本語化できていることが確認できました!
まとめ
Webアプリケーションでユーザが入力されたデータが正しい形式であるかを確かめるには、バリデーションチェックを行います。
またデータに誤りがあれば、それをユーザに伝えて再度値を入力し直してもらう必要があります。
モデルにバリデーションを設定しておくことで、データベースに登録するデータを簡単に検証することができます。
バリデーション機能は頻繁に使用しますので、慣れておきましょう。
また、アプリケーションのユーザビリティ向上のためにエラーメッセージの日本語化も確実に身につけておきたいですね。
ひとりではなかなかプログラミングの学習が続かない、未経験だから不安が多い、という方はプログラミングスクールを利用してみるのも有効です。
本物のエンジニアに学ぶことで、時間がない方でも最短でスキルを身につけることができます。
現役エンジニアのパーソナルメンターからマンツーマンで学べる
お悩みの方は、まずは無料キャリアカウンセリングにお申込みください。
関連記事
RubyのフレームワークといえばRuby on Railsです。
そもそもフレームワークとは何かということから、Ruby on Railsの基本理念や設計思想まで、プログラミング未経験の方にもわかりやすくご紹介!
また、インストール方法から最初の画面を表示するまでの流れについても解説しています。
早速Ruby on RailsでWebアプリケーションを作ってみたい方必読!
初心者の方でも挫折することなく、コマンド一発でToDoアプリを完成させることができる方法をご紹介。
Railsを学び始めようと思っている方から、フレームワークについて学びたいけどいまいちメリットがわからない方まで、ぜひ一度お試しください!
Ruby on Railsなどの多くのフレームワークが採用しているMVCアーキテクチャにおいて、データベースとのやり取りを引き受けているのがモデルです。
RailsではActive RecordというORMが使われており、データベースのデータをオブジェクト指向に対応させて取り扱うことができます。
Active Recordの使い方をマスターして、Railsへの理解を深めましょう!
多くのWebアプリで一般的に利用されているリレーショナルデータベースでは、複数のテーブルを関連付けることができます。
Ruby on RailsのORMであるActive Recordにも、モデル同士のリレーションを表現するためのアソシエーションという機能があります。
アソシエーションをマスターして、より複雑なデータベース設計を身につけましょう!
Ruby on RailsはMVCアーキテクチャを採用しており、リクエストを受けてからレスポンスを返すまでのライフサイクルを理解しておくことは非常に重要です。
この流れをしっかり学んでおくだけで、驚くほどアプリケーション開発がしやすくなります!
コメントを書く