【開発現場で使える!】Ruby on RailsでのValidationの使い方
サービス開発では必須となるValidation。Ruby on RailsでのValidation(バリデーション)の使い方について解説しています。今すぐ現場でも使える技術でしょう。
テックアカデミーマガジンは受講者数No.1のプログラミングスクール「テックアカデミー」が運営。初心者向けにプロが解説した記事を公開中。現役エンジニアの方はこちらをご覧ください。 ※ アンケートモニター提供元:GMOリサーチ株式会社 調査期間:2021年8月12日~8月16日 調査対象:2020年8月以降にプログラミングスクールを受講した18~80歳の男女1,000名 調査手法:インターネット調査
監修してくれたメンター
mentor-hakamata
C#, Ruby, Python, JavaScriptなど経験。
普段サイトなどで会員登録をする際に「パスワードは最低8文字以上でなければなりません」といった文言をよく見るかと思います。
こういった制約をRubyのフレームワークのRuby on Railsではバリデーション(Validation)という仕組みで用意することができます。
ここではValidationの使い方について、テックアカデミーのメンター(現役エンジニア)が実際のコードを使用して初心者向けに解説します。
目次
Rubyについてそもそもよく分からないという方は、Rubyとは何なのか解説した記事を読むとさらに理解が深まります。
今回はバリデーションについて説明するよ。
田島メンター!!バリデーションというのは何ですか〜?
バリデーションは、ある値に対して指定した条件に当てはまるかどうかというのを検証するものだよ。例えばメールアドレスが正しく入力されているかとか、パスワードの文字は8文字以上であるかとかだね。
なるほど、実際によく見るやつですね。ぜひ覚えておきたいです!
バリデーションとは
Ruby on Railsには、ユーザが入力した値を検証する為にバリデーション(Validation)という仕組みがあります。
例えば入力必須の項目や、最低何文字以上入力必須などの制約を設ける際に利用します。
この仕組みを利用すれば、データベースに不正なデータが登録されることを防ぐことができます。
例えば、あるWEBサイトで年齢を入力する欄があったとします。
何も対策していない状態で-1を入力して登録ボタンを押してしまうと、-1が年齢としてデータベースに登録されてしまいます。
このような不正な状態が起きないようにするため、バリデーションを利用します。
おかしい値が入力された場合は「年齢に不正な値が入力されています」といったエラーメッセージを表示し、登録されないようにします。
これがバリデーションの役割です。
バリデーションの構文
バリデーションはモデルに対応するファイルに記載していきます。
例えばUserモデルのnameに対して、必須入力であることを表すバリデーションを設定する場合は以下のように書きます。
class User < ApplicationRecord validates :name, presence: true end
これでnameの入力は必須になりました。
nameの入力がない状態でUserを保存しようとするとこのようなエラーになります。
Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)
nameが空白の状態だというメッセージが表示されていますね。
バリデーションにはいくつか種類がありますので、のちほど説明します。
バリデーションがトリガーされるメソッド
バリデーションがトリガー(実行)されるメソッドがいくつかあるので紹介します。
create
データベースに登録するときに使用するメソッドです。
User.create(name: "tarou")
バリデーションで不正なデータが見つかった場合はデータベースに保存されません。
create!
createメソッドと同じくデータベースに登録するときに使用するメソッドです。
User.create!(name: "tarou")
createメソッドと異なるのは、バリデーションで不正なデータが見つかった場合は例外エラーとして処理されます。
前述でも紹介した
Validation failed: Name can't be blank (ActiveRecord::RecordInvalid)
このようなエラーが表示され、実行中の処理は止まります。
save
データベースに登録するときに使用するメソッドです。
User.new(name: "tarou").save
正常に保存できた場合はtrue、保存できなかった場合はfalseを返します。
save!
saveメソッドと同じくデータベースに登録するときに使用するメソッドです。
User.new(name: "tarou").save!
saveメソッドと異なるのは、バリデーションで不正なデータが見つかった場合は例外エラーとして処理されます。
実行中の処理は止まります。
update
すでに存在するデータを更新するときに使用するメソッドです。
User.update(name: "tarou")
正常に更新できた場合はtrue、更新できなかった場合はfalseを返します。
update!
updateメソッドと同じくデータを更新するときに使用するメソッドです。
User.update!(name: "tarou")
updateメソッドと異なるのは、バリデーションで不正なデータが見つかった場合は例外エラーとして処理されます。
実行中の処理は止まります。
valid?メソッド
valid?メソッドはバリデーションの結果を確認できます。
user = User.first user.name = "tarou" user.valid?
valid?メソッドを実行したときのモデルの状態でバリデーションを実行します。
不正なデータが見つかった場合はfalseを、問題なければtrueを返します。
データベースへの保存はしません。
バリデーションがスキップされるメソッド
逆にバリデーションがスキップされる(実行されない)メソッドもありますので注意してください。
バリデーションはスキップしますが、データベース上の制約に引っかかる場合はデータベース側での保存時にエラーになりますのでご注意ください。
increment!
increment!メソッドはある数値項目をいくつか増分して、保存するメソッドになります。
以下の例はユーザーのidを1増やして、データベースに保存しています。
user = User.first user.increment!(:id, 1)
また増分ではなく減算をするdecrement!メソッドもあります。
こちらもバリデーションはスキップします。
increment_counter
increment_counterメソッドもある数値項目を増分させるメソッドですが、複数のデータを対象に更新できます。
以下の例はユーザーのageが25であるユーザーのageを1増やして、データベースに保存しています。
User.increment_counter(:age, 25)
また増分ではなく減算をするdecrement_counterメソッドもあります。
こちらもバリデーションはスキップします。
toggle!
toggle!メソッドは真偽値(true/false)を反転させて、データベースに保存します。
以下の例はユーザーのanswered(アンケートなどの回答有無)を反転させています。
user = User.first user.toggle!(:answered)
touch
touchメソッドはupdated_at(更新日時)を更新して、データベースに保存します。
user = User.first user.touch
update_all
update_allメソッドは複数のデータに対して、項目を更新し、データベースに保存します。
以下の例はすべてのユーザーのnameをtarouに更新しています。
User.update_all(name: "tarou")
update_attribute
update_attributeメソッドは指定した項目を更新し、データベースに保存します。
以下の例はユーザーのnameをtestに更新しています。
user = User.first user.update_attribute(:name, "test")
update_column
update_columnメソッドは指定した項目のみを更新し、データベースに保存します。
update_attributeメソッドと異なる点は、updated_atの更新はされないということです。
以下の例はユーザーのnameをtestに更新しています。
user = User.first user.update_column(:name,"test")
update_columns
update_columnsメソッドは複数項目を更新し、データーベースに保存します
updated_atは更新されません。
以下の例はユーザーのidを100に、nameをtestに更新しています。
user = User.first user.update_columns(id: 100, name: "test")
update_counters
update_countersメソッドは条件に合致したユーザーの項目を増分させて、データベースに保存します。
以下の例はidが1~100のユーザーのageを1増分しています。
User.where(id: 1..100).update_counters(age: 1)
バリデーションの種類
バリデーションの種類を紹介します。
バリデーション | バリデーションの内容 |
acceptance | チェックボックスがチェックされているかどうかをチェック |
validates_associated | 関連しているモデルのバリデーションも実行 |
confirmation | フォームで入力された2つの値が等しいかをチェック |
comparison | 2つの値を任意の比較方法(AはBより大きい、A=Bであるかどうか)でチェック |
exclusion | 指定した値が含まれていないかをチェック |
format | 正規表現で指定したフォーマットで入力されているかをチェック |
inclusion | 指定されている値が入力されているかチェック(A, Bしか入力できないが、Cが入力されている場合はエラー) |
length | 入力値の桁数をチェック |
numericality | 決まった数値が入力されているかをチェック |
presence | 入力値が空ではないことをチェック |
absence | 入力値が空であることをチェック |
uniqueness | 他のデータと重複した値になっていないかをチェック |
validates_with | 独自のバリデーションを作成できる |
validates_each | チェック対象のモデルの項目を全て任意で使用して独自のバリデーションを作成することができる |
興味があれば調べてみましょう。
使用頻度が高いバリデーションについては次で説明をします。
使用頻度の高いバリデーション
使用頻度の高いバリデーションをコードを書きながら説明します。
空でないこと確認する:presence
presenceは入力値が空ではないことを検証します。
以下の例ではユーザーのnameが空ではないことを検証します。
class User < ApplicationRecord validates :name, presence: true end
重複を制限する:uniqueness
uniquenessは入力値がほかのデータと重複していないことを検証します。
以下の例ではユーザーのnameがほかのユーザーと重複していないかを検証します。
class User < ApplicationRecord validates :name, uniqueness: true end
特定の値を制限する:inclusion、exclusion
inclusionは、指定した入力値のリストに含まれる値が入力されているかを検証します。
逆にexclusionは、指定した入力値のリストに含まれない値が入力されているかを検証します。
inclusion = ホワイトリスト、exclusion = ブラックリストのイメージです。
以下の例ではユーザーのnameがtarou, zirou, saburouのどれかであることを検証します。
class User < ApplicationRecord validates :name, inclusion: { in: %w(tarou zirou saburou) end
以下の例ではユーザーのnameがtarou, zirou, saburouのどれにもあてはまらないことを検証します。
class User < ApplicationRecord validates :name, exclusion: { in: %w(tarou zirou saburou) end
数値のみを許可する:numericality
numericalityは、入力値が数値であることを検証します。
以下の例ではユーザーのageが数値であることを検証します。
class User < ApplicationRecord validates :age, numericality: true end
また整数のみを許可したい場合は以下のように記載します。
class User < ApplicationRecord validates :age, numericality: { only_integer: true } end
文字数を制限する:length
lengthは、入力値が指定した桁数以内になっているかを検証します。
以下の例ではユーザーのnameが5桁以上であることを検証します。
class User < ApplicationRecord validates :name, length: { minimum: 5 } end
以下の例ではユーザーのnameが100桁以下であることを検証します。
class User < ApplicationRecord validates :name, length: { maximum: 100 } end
以下の例ではユーザーのnameが1桁以上100桁以下であることを検証します。
class User < ApplicationRecord validates :name, length: { in: 1..100 } end
以下の例ではユーザーのnameが10桁であることを検証します。
class User < ApplicationRecord validates :name, length: { is: 10 } end
正規表現を使用する:format
formatは、入力値が正規表現で指定されたフォーマットになっているかを検証します。
以下の例ではユーザーのnameが半角英文字であることを検証します。
class User < ApplicationRecord validates :name, format: { with: /\A[a-zA-Z]+\z/ } end
実際にバリデーションを使ってみよう
例えば、Userモデルに関する場合は、「app/models/user.rb」というファイルにバリデーションを設定します。
以下では、実際にバリデーションを設定してブラウザ上でどのように表示されるのか解説していきます。
入力必須にする
例えばユーザ作成時のユーザ名など、必ず入力しなければいけない項目に対してはpresenceオプションを設定してみます。
class User < ApplicationRecord validates :name, presence: true end
この状態でnameを空でユーザ作成しようとするとエラーが表示されます。
一番シンプルな例で見てみようか。これは名前の欄が空白の場合エラーメッセージを出すようにしたものだよ。presenceというのは「空白でない場合にtrue」となるものなんだ。
逆に言うと、空だった場合はfalseとなるわけですね。
そうだね。他にも色々なバリデーションの例を見てみよう。
重複不可にする
ユーザ名の重複を許したくない場合にはuniquenessオプションを設定します。
class User < ApplicationRecord validates :name, presence: true, uniqueness: true end
先ほどのpresenceオプションは残したまま、uniquenessオプションを追加することが可能です。
重複のテストをするために予めtarouというユーザを作成してから確認します。
新たにtarouというユーザ名でユーザを作成しようとするとエラーが表示されます。
文字数に制限を設ける
例えば最小文字数や最大文字数を設定することができ、その文字数に達していない場合、超えている場合はエラーが表示されます。
文字数に制限を設ける場合にはlengthオプションを使用します。
最低文字数の制約を設ける場合はminimum属性を指定して設定します。
class User < ApplicationRecord validates :name, presence: true, uniqueness: true, length: { minimum: 3 } end
minimum属性は設定した文字数以上の文字数でなければエラーが発生します。
今回は3を設定してありますので3文字以上の文字数でない場合にはエラーが表示されます。
最大文字数の制約を設ける場合にはmaximum属性を指定して設定します。
class User < ApplicationRecord validates :name, presence: true, uniqueness: true, length: { maximum: 8 } end
maximum属性は設定した文字数以下の文字数でなければエラーが発生します。
今回は8を設定してありますので8文字以下の文字数でなければエラーが発生します。
また、lengthオプションの属性については同時に設定することが可能です。
最低◯◯文字以上〜最大◯◯文字以下という指定をすることが出来ます。
class User < ApplicationRecord validates :name, presence: true, uniqueness: true, length: { minimum: 3, maximum: 8 } end
上記の例の場合は、最低3文字以上 最大8文字以下で入力しないとエラーが発生します。
数値の制限する
年齢にもバリデーションを設定してみましょう。
例えば18歳以上でなければエラーを発生させるにはどのように設定すればよいでしょうか?
数値の制限を行うにはnumericalityオプションを使用します。
class User < ApplicationRecord validates :name, presence: true, uniqueness: true, length: { minimum: 3, maximum: 8 } validates :age, numericality: { greater_than_or_equal_to: 18 } end
greater_than_or_equal_toという属性は文字通り、設定した値と等しいまたは大きい場合のみ許可する属性です。
以上、バリデーションの設定方法を紹介しました。
SNSのような会員登録が必要なサービスでは、バリデーションが必須となります。
ぜひ現場でも使えるように覚えておきましょう。
代表的なバリデーションを紹介したよ。
よく見ると、それぞれの条件でちゃんとエラーメッセージが対応したものになっていますね。
これは元々デフォルトのエラーメッセージが用意されていて、それが表示されているんだ。非常に多くのデフォルトメッセージがあるけれど、全て公式のガイドで確認することができるよ。
そんなところまで準備されているんですね。また調べてみます!
Ruby on Railsを学習中の方へ
これで解説は終了です、お疲れさまでした。
- つまずかず「効率的に」学びたい
- 副業や転職後の「現場で使える」知識やスキルを身につけたい
プログラミングを学習していて、このように思ったことはありませんか?
テックアカデミーのWebアプリケーションコースでは、第一線で活躍する「プロのエンジニア」が教えているので、効率的に実践的なスキルを完全オンラインでしっかり習得できます。
合格率10%の選考を通過した、選ばれたエンジニアの手厚いサポートを受けながら、Ruby on Railsを使ったWebアプリケーション開発を学べます。
まずは一度、無料体験で学習の悩みや今後のキャリアについて話してみて、「現役エンジニアから教わること」を実感してみてください。
時間がない方、深く知ってから体験してみたい方は、今スグ見られる説明動画から先に視聴することをおすすめします!