【Rails入門】ActiveRecord::Validation::valid?で検証しよう

今回は、すでに侍エンジニア塾ブログの別の記事でも書かれているバリデーション(Validation)について、追加情報を仕入れましたのでお伝えします。

Ruby on Rails(以降、Rails)には、ユーザがフォームで入力した値が、開発者が決定したルールに沿っていることを検証するためにバリデーション(Validation)機能が用意されています。

この記事では、(バリデーションを行わずに)オブジェクトを作成した後、任意のタイミングでバリデーションを行う方法を紹介します。

また、応用編としてコンテキストと呼ばれるモノを指定し、状況に応じてバリデーションの内容を切り替える方法も紹介しています。

バリデーションとは

オブジェクトのデータに不適切な内容が設定されていないか検証する機能を、バリデーションと呼びます。

以下のようなバリデーションがよく行われます。

  • 電話番号欄に、数字以外の文字を入力していないか
  • メールアドレス欄に、メールアドレスとして不適切な文字列が設定されていないか
  • 郵便番号欄に、数字3桁+ハイフン(-)+数字4桁以外の文字を入力していないか

ユーザがフォームに入力した内容を検証する方法は、以下の記事で紹介されていますので、あわせてご覧ください。

【Rails入門】バリデーション(validations)の使い方まとめ
更新日 : 2018年6月18日

バリデーションによって、誤ったデータを入力したことをユーザに気付かせ、正しいデータを再入力する仕組みを簡単に実装できます。

ActiveRecord::Validation::valid?とは

この記事で扱うActiveRecord::Validation::valid?は、任意のタイミングでオブジェクトのバリデーション(検証)を行うメソッドです。

たとえば、(ユーザがフォームで入力するのではなく)プログラムでオブジェクトを作成する場合に、ActiveRecord::Validation::valid?メソッドを使ってバリデーションを行います。

あくまでイメージですが、以下のような流れになります。

上記のように適当なオブジェクトを作成した後、以下のようにバリデーションを行います。

仮に問題があった場合は、member.errors.messagesでエラーメッセージを確認できます。

動作を理解するためのWebアプリを作成する

ActiveRecord::Validation::valid?メソッドのイメージがわかったところで、動作を確認するために、Rails 5.1をインストールしてWebアプリを作りましょう。

(1)Railsをインストールします。

私は、以下の記事を参考に、VirtualBoxで作成した仮想パソコンにインストールしたLinux Mintに、Railsの開発環境を作成しました。

基本的には記事の手順に従って操作しますが、app/samurai/sample1ディレクトリを作成する代わりに、app/samurai/valid-demoディレクトリを作成しました。

Railsを起動して、ブラウザで画面が表示されることを確認したら、いったんRailsを終了してから次に進みます。

初心者でもかんたん!Ruby on Rails の開発環境の構築手順(Mac/Windows 両対応)
更新日 : 2019年8月9日

Linux Mintのインストールについては、以下の記事で詳しく説明しています。

Linux Mint Cinnamonエディションを使ってみよう
更新日 : 2019年5月22日

(2)新しい「端末」を起動して、以下のコマンドを1行ずつ順番に入力します。

(3)app/models/member.rbを編集します。

変更前:

変更後:

これで準備完了です。

このコードでバリデーション(検証)される内容は、以下のとおりです。

カラムバリデーション内容
name作成時(on: :create)は、1~10文字
更新時(on: :update)は、1~20文字
※コンテキストを指定したパターンです。
emailメールアドレスらしい文字列(正規表現[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)
mail_magazineがtrueの場合は、必須
post_code数字3桁+ハイフン(-)+数字4桁(正規表現[0-9]{3}-[0-9]{4})に従う文字列
※独自のバリデーションメソッドを作成するパターンです。
tel整数のみ
空欄を認める
その他post_codeとtelは、検証前に先頭と末尾のスペースを除去する

なお、emailの「メールアドレスらしい文字列(正規表現)」は、「HTML 5.2 W3C Recommendation, 14 December 2017」を利用しています。

詳しくは、以下のページをご覧ください。

参考:https://www.w3.org/TR/html5/forms.html#valid-e-mail-address

ActiveRecord::Validation::valid?を使ってみよう

では、Railsコンソールで、ActiveRecord::Validation::valid?を使ってみましょう。

ActiveRecord::newでバリデーションせずにオブジェクトを作成する

ActiveRecord::createを使うと、バリデーションが行われ、ActiveRecord::Validation::valid?の出番がなくなります。

そこで、ActiveRecord::newを使い、バリデーションを省略してオブジェクトを作成しましょう。

(1)新しい「端末」で以下のコマンドを1行ずつ順番に入力します。

(2)以下のコードを入力します。

実行結果:

app/models/member.rbを編集したときに、作成時(on: :create)はnameの文字数が1文字から10文字まで(つまり省略できない)に制限していました。

それでも、何ごともなかったかのようにMemberが作成されました。

ActiveRecord::Validation::valid?でバリデーションする

続けて、バリデーションを実行してみましょう。

(1)以下のコードを入力します。

実行結果:

false(失敗)と表示されました。

バリデーションの結果、何かしら問題が発生しているようですが、詳細は分かりません。

エラーメッセージを確認してみましょう。

(2)以下のコードを入力します。

実行結果:

nameが短すぎる(最低1文字)ことがわかりました。

次は、複数のバリデーションエラーを発生させてみましょう。

(3)以下のコードを1行ずつ順番に入力します。

実行結果:

何かしら問題が発生しているようですが、詳細は分かりませんので、エラーメッセージを確認しましょう。

(4)以下のコードを入力します。

実行結果:

以下の4つのエラーメッセージが確認できます。

  • :name=>[“is too short (minimum is 1 character)”],
  • :email=>[“can’t be blank”],
  • :post_code=>[“は、数字3桁+ハイフン(-)+数字4桁の形式で入力してください。value = 123”],
  • :tel=>[“is not a number”]}

エラーメッセージに対応せずに、保存してみましょう。

(5)以下のコードを入力します。

実行結果:

保存しようとしますが、保存に失敗し、ロールバックしています。

ここで紹介した例のように、バリデーションに失敗しているオブジェクトは保存できません。

※member.save(validate: false)とすれば、強制的に保存できます。

ActiveRecord::saveでオブジェクトを保存する

あれこれ配慮して、バリデーションエラーが発生しない状態にしてから、ActiveRecord::saveでオブジェクトを保存するのが良いでしょう。

オブジェクトを保存してみます。

(1)以下のコードを入力します。

実行結果:

バリデーションエラーが発生していません。

念のためエラーメッセージも確認してみましょう。

(2)以下のコードを入力します。

実行結果:

こちらも何もありませんね。

(3)以下のコードを入力します。

実行結果:

無事に保存できました。

この後の説明の都合、Railsコンソールを終了しておきましょう。

(3)以下のコードを入力します。

コンテキストを指定してバリデーションする

コンテキストと呼ばれるモノを指定すると、状況に応じてバリデーションの内容を切り替えられます。

たとえば、初めてデータベースに登録するときはnameは10文字までに制限されているけれど、更新時は20文字まで許可するといったこともできます。

ただ、これが便利!と思える状況が思いつかないのですが…、できることなので紹介しておきましょう。

app/models/member.rbの以下の部分に注目してください。

これが、コンテキストによってバリデーションの内容を切り替えているコードです。

このコードがどのように動作するのか確認してみましょう。

(1)「端末」で、以下のコマンドを入力します。

(2)以下のコードを1行ずつ順番に入力します。

実行結果:

ここでは、nameに20文字の文字列を設定して、新規作成しています。

新規作成時は、「on: :create」が指定された行のバリデーションによって、バリデーションエラーが発生します。

次に、コンテキストを変更し、更新時(「on: :update」が指定された行)のバリデーションで検証してみましょう。

(3)以下のコードを入力します。

実行結果:

今度は「context: :update」を指定することで、「on: :update」が指定された行のバリデーションによって、バリデーションエラーが発生していません。

まとめ

今回は、任意のタイミングでバリデーションを行うActiveRecord::Validation::valid?の使いかたを紹介しました。

問題が発生したときにエラーメッセージを取得する方法や、コンテキストを指定してバリデーションの内容を切り替える方法も理解できたでしょうか。

バリデーションは、緩すぎても、厳しすぎても使い勝手が悪くなってしまいますので、色々なパターンを試してみて、ユーザによってちょうど良い設定を探してみてくださいね!

それでは!

LINEで送る
Pocket

最短でエンジニアを目指すなら侍エンジニア塾

cta_under_bnr

侍エンジニア塾は業界で初めてマンツーマンレッスンを始めたプログラミングスクールです。これまでの指導実績は16,000名を超え、未経験から数多くのエンジニアを輩出しています。

あなたの目的に合わせてカリキュラムを作成し、現役エンジニア講師が専属であなたの学習をサポートするため効率よく学習を進めることができますよ。

無理な勧誘などは一切ありません。まずは無料体験レッスンを受講ください。

無料体験レッスンの詳細はこちら

書いた人

侍テック編集部

侍テック編集部

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説