検索
連載

ActiveRecordの基本機能とマイグレーション、バリデーション開発現場でちゃんと使えるRails 4入門(5)(3/3 ページ)

エンタープライズ領域での採用も増えてきたRuby on Railsを使ってWebアプリケーションを作るための入門連載。最新版の4に対応しています。今回は、Railsのモデル機能を担うActiveRecordの基本的なメソッドに加え、where、order、limitを紹介。DBマイグレーションやバリデーションも。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

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技術者認定シルバー試験問題作成者)

平成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.

前のページへ |       
ページトップに戻る