ActiveRecordの基本機能とマイグレーション、バリデーション:開発現場でちゃんと使えるRails 4入門(5)(3/3 ページ)
エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、Railsのモデル機能を担うActiveRecordの基本的なメソッドに加え、where、order、limitを紹介。DBマイグレーションやバリデーションも。
ActiveRecordのバリデーション「validates」メソッド
ActiveRecordは属性の値がデータベースに反映される前に適切であるかを検証するバリデーションの仕組みも用意しています。以下に属性が空でないことを検証するバリデーションの例を示します。
class User < ActiveRecord::Base validates :name, :department, presence: true end User.create(name: 'イブ', department: '人事部') # 保存される User.create(department: '人事部') # 保存されない
バリデーションはデータベースにデータを保存・更新するメソッド、すなわち「create(create!)」「save(save!)」「update(update!)」を呼び出したときに実行されます。「!」付きのメソッドはバリデーション失敗時に例外を発生します。
エラーの確認ができる「errors.messages」メソッド
オブジェクトがバリデーションを実行し失敗すると、オブジェクトは「errors.messages」メソッドでエラーの内容を教えてくれます。
u = User.create(department: '人事部') u.errors.messages # => {name:["can't be blank"]}
また、特定の属性について調べたいときは次のようにします。
u.errors[:name] # => ["can't be blank"]
全ての属性のエラーを一次元の配列で得る「errors.full_messages」メソッド
さらに、全ての属性のエラーを一次元の配列で得る「errors.full_messages」というメソッドも用意されています。この仕組みを用いて、Railsのscaffoldで生成されたオブジェクトのフォームは次のようにしてバリデーションエラーを通知しています。
<%= form_for(@book) do |f| %> <% if @book.errors.any? %> <div id="error_explanation"> <h2> <%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved: </h2> <ul> <% @book.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
validatesメソッドで使える主なバリデーション10選
ここではActiveRecordが用意しているバリデーションでよく使われるものを紹介します。
validatesメソッドは属性に対して複数のバリデーションを設定できます。また、1つのvalidatesメソッドでバリデーションを掛ける属性も複数指定できます。
validatesメソッドはバリデーションの種類をハッシュのキーとして指定します。取り得る値はバリデーションによって異なりますが、いずれのバリデーションでも「:on」「:message」をキーとするハッシュとすることができます。
:onは値に「:create」か「:update」をとり、バリデーションを実行するタイミングを新規保存時か更新時のいずれかに限定します。:messageはデフォルトのエラーメッセージを値の文字列に変更できます。
- 【1】presence:値が空でないかを検証
presenceのバリデーションは対象の属性の値が空でないかを検証します。
validates :name, presence: true
- 【2】length:指定した属性の長さを検証
lengthのバリデーションは指定した属性の長さを検証します
# nameが2文字以上・32文字以下であるかを検証 validates :name, length: { minimum: 2, maximum: 32, message: '2文字以上・32文字以下としてください' }
lengthは次のオプションをとります。
- minimum:最短の長さ。値に数値をとる
- maximum:最長の長さ。値に数値をとる
- in:長さが範囲に収まっているか。値に範囲オブジェクトをとる
- is:長さがちょうどその数値であるか
- 【3】format:指定した属性が正規表現にマッチするかを検証
formatのバリデーションは指定した属性が正規表現にマッチするかを検証します。
# zip_codeが適切なフォーマットであるかを検証 validates :zip_code, format: { with: /^\d{3}\-?\d{4}$/ }
このように、「with」オプションに正規表現オブジェクトを渡すと、それにマッチするかを検証してくれます。
- 【4】uniqueness指定した属性がデータベース中で重複がないかを検証
uniquenessのバリデーションは指定した属性がデータベース中で重複がないかを検証します。
# emailに重複がないかを検証 validates :email, uniqueness: true
- 【5】numericality:指定した属性が数値であるかを検証
numericalityのバリデーションは指定した属性が数値であるかを検証します。
validates :average, numericality: true validates :last_score, numericality: { only_integer: true }
「only_integer」オプションを渡すと、整数であるかも検証してくれます。
- 【6】inclusion:指定した属性が配列または範囲に含まれているかを検証
inclusionのバリデーションは指定した属性が配列または範囲に含まれているかを検証します。
validates :age, inclusion: { in: 0..19, on: :create }
- その他4つ
この他にも以下のバリデーションが用意されています。
- 【7】acceptance:チェックボックスにチェックが入っているかを検証
- 【8】confirmation:確認用の一時属性と値が同じかどうかを検証
- 【9】exclusion:inclusionの逆で属性が配列または範囲に含まれていないかを検証
- 【10】absence:空白であることを検証
validatesメソッドの便利なオプション
validatesメソッドには、さらに便利なオプションを渡すことができます。
- 属性が空の時、バリデーションをスキップ「allow_nil」
validates :zip_code, format: { with: /^\d{3}\-?\d{4}$/ }, allow_nil: true
- バリデーションの実行条件を定義「if」「unless」
シンボルを渡すと、その名前のメソッドが実行され、返り値が判定に用いられます。文字列の場合は、Rubyのコードとして実行され、その結果が判定に用いられます。
validates :tel, presence: true, if: :contact_by_phone? validates :company, presence: true if: "name.nil?" def contact_by_phone? contact_type == 'phone' end
またifとunlessオプションにはProcオブジェクトを渡すこともできます。
バリデーションのスキップ
以下に挙げるメソッドなどはバリデーションをスキップします。
- update_all:whereで得られたモデルオブジェクトの集合全てに対して更新を行うメソッド
- update_attribute:バリデーションをせず、特定のカラムを更新するモデルオブジェクトのメソッド
- update_column:バリデーションとコールバックをせず、特定のカラムを更新するモデルオブジェクトのメソッド
- update_columns:バリデーションとコールバックをせず、複数のカラムを更新するモデルオブジェクトのメソッド
カスタムバリデーションも作れる
Railsのバリデーションの機能は豊富で、標準のものだけでも事足りることがほとんどです。それでもカスタムバリデーションを作りたい場合には、そのための仕組みも用意されています。
また、次回紹介する「モデル間の関連」の機能と併せて関連先・関連元のオブジェクトのバリデーションを行うこともできます。ですが、それらの機能が必要になるケースはそう多くはないため、必要になったときに身に付けるのがいいでしょう。
次回は、モデル間の関連とコールバック
今回はActiveRecordの基本的な機能とマイグレーション、そしてバリデーションについて紹介しました。ActiveRecordの体系は巨大ですが、いずれの機能もアプリケーションの設計の上でとても重要です。
次回はモデル間の関連とコールバックについて解説していきます。お楽しみに。
- Railsアプリの設計をMVCごとに見直しリファクタリングして連載総まとめ
- 「設定より規約」のRailsで必要なセッティングの基礎知識と国際化/多言語対応
- ActionMailerのSMTP設定、テンプレートで送信&ActiveModelの基本的な使い方とバリデーション
- RailsテストフレームワークRSpecのインストールと基本的な使い方、基礎文法
- RailsのテンプレートエンジンSlimの書き方とActionViewのヘルパーメソッド、レイアウトの使い方
- Rails開発を面白くするアクションコントローラーの5大機能とルーティングの基本
- ActiveRecordにおけるモデルの「関連」とコールバックの使い方
- ActiveRecordの基本機能とマイグレーション、バリデーション
- 現場で使えるか見極めたいRails 4.1の新機能8選
- 特定データに関するscaffoldアクションの実装&基礎的なリファクタリング手法
- scaffoldの中身を理解するためにMVCコンポーネントと7つのアクションを個別で自作する
- 簡単インストールから始める初心者のためのRuby on Railsチュートリアル
著者プロフィール
林 慶(Rails技術者認定シルバー試験問題作成者)
平成2年大阪生まれ。2006年から高専で情報工学を学んでいたが当時は所謂プログラミングができない工学生だった。卒業後、高専の専攻科に上がったもののマンネリ化したキャンパスライフに飽きたため休学して渡豪。そこでプログラミングに対するコンプレックスを克服するためにRuby on Railsなどでアプリケーションを作ることを覚える。
帰国後から現在までは復学し推薦システムに関する研究を行いながら、アジャイルウェアでRuby on Railsアプリケーションの開発業務に従事している。
好きなメソッドはinject。
監修者プロフィール
山根 剛司(Ruby業務開発歴7年)
兵庫県生まれ。1997年からベンチャー系のパッケージベンダーで10年間勤務。当時、使用していた言語はJavaとサーバーサイドJavaScript。
2007年よりITコンサル会社に転職し、Rubyと出会って衝撃を受ける。基幹システムをRuby on Railsで置き換えるプロジェクトに従事。それ以来Ruby一筋で、Ruby on Railsのプラグインやgemも開発。
2013年より、株式会社アジャイルウェアに所属。アジャイルな手法で、Ruby on Railsを使って企業向けシステムを構築する業務に従事。
Ruby関西所属。好きなメソッドはtap。
Twitter:@spring_kuma、Facebook:山根 剛司
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Ruby on Rails3で学ぶWeb開発のキホン(3):「ActiveRecord」の基本とデータの参照
今回はRailsの最も重要なライブラリの1つ、ActiveRecordについて、基本的な使い方をご紹介します。 - Ruby on Rails3で学ぶWeb開発のキホン(4):ActiveRecordの更新系操作
前回はActiveRecordを使った参照について解説しましたが、今回は登録、更新、削除などの更新系を中心に見ていきます。 - Railsコードリーディング〜scaffoldのその先へ〜(3):ActiveRecordを使ったソースコードを読もう
DBアクセス処理の部分を扱うActiveRecordを読んでいこう。データの検索、更新、検証をどうすべきか - 3rdRailによるRailsプログラミング入門(2):ActiveRecordが提供するModel機能を理解しよう
アプリを拡張する手順を学ぼう。ファインダ、バリデーション、アソシエーション、マイグレーションとは? - DB2でさくさく実現するRESTfulなDBアプリ(2):Railsでレガシーデータを蘇えらせるテクニック
古いデータベースの再利用アプリ、どう作る? Railsなら効率よく連携でき、マッシュアップなどの要求にも応えやすいんです - 資格試験は転職に役立つか:Rails技術認定試験がスタート、合格者に聞いた
- @IT自分戦略研究所 資格辞典:Rails技術者認定試験(Rails 3 Certified Programmer)