第3回 ActiveRecordを使ったソースコードを読もう

倉貫 義人
松村 章弘
TIS株式会社
SonicGarden

2009/1/28

値の検証(バリデーション)

 ActiveRecordを使うと、データ保存時の値の検証(バリデーション)もメソッドを用いて簡単に実装できます。

 前節で紹介したsaveメソッドで保存に失敗するのは、主にこのバリデーションで正しい値でないと判断された場合に起こります。Userモデルのバリデーションを見てみましょう。

38
39
40
41
42
43
44
45
46
47
48
49
50
validates_presence_of :name, :message => 'は必須です'
validates_length_of :name, :maximum => 60, :message => 'は60桁以内で入力してください'

validates_presence_of :password, :message => 'は必須です', :if => :password_required?
validates_confirmation_of :password, :message => 'は確認用パスワードと一致しません', :if => :password_required?
validates_length_of :password, :within => 6..40, :too_short => 'は%d文字以上で入力してください', :too_long => 'は%d文字以下で入力して下さい', :if => :password_required?

validates_presence_of :password_confirmation, :message => 'は必須です', :if => :password_required?

validates_presence_of :email, :message => 'は必須です'
validates_length_of :email, :maximum => 50, :message => 'は50桁以内で入力してください'
validates_format_of :email, :message => 'は正しい形式で登録してください', :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/
validates_uniqueness_of :email, :case_sensitive => false, :message => 'は既に登録されています。'
app/models/user.rb

 Userモデルにおけるバリデーションには、例えば「名前(name)は必須、かつ、60けた以上の値を入れてはいけない」というものがあります。それを表現したのが、38行目、39行目になります。このように、validates_xxx_ofという形で、モデルの中に記述することで簡単にバリデーション処理を実現することができます。

 必須チェック、けた数チェックのほかにも、あらかじめ一般的な検証メソッドがいくつも用意されているので、それらを使い1行で表現することができます。

 こうしたバリデーションは、saveメソッドの実行時に判定されます。もしもバリデーションに引っ掛かるような値が設定された状態でsaveメソッドが呼ばれた場合は、保存に失敗したうえで、バリデーションのエラーの内容が、保存しようとしたオブジェクトの中に格納されて返されます。コントローラ側でそれを受けて、以下のようなバリデーションエラー画面を出すことが多いです。

図4 バリデーションエラー

コールバック

 バリデーションの処理は、Railsフレームワークが保存時に自動的に行ってくれます。しかし、保存処理などの任意のタイミングで、自分で記述した処理を実行させたい場合もあると思います。そういったニーズに応えるのが、コールバックと呼ばれる機能です。

 実際にSKIPで使っている個所を紹介しましょう。SKIPのUsersテーブルにあるsectionというカラムがあり、そこにはユーザーの所属する部署の値が入ります。その値は自由入力形式で登録することができるため、大文字・小文字、全角・半角などの入力のぶれが発生し、検索時にうまくヒットさせることができない場合が出てきます。

 そこで、SKIPではコールバック機能を使い、保存前に入力のぶれを統一する処理を入れています。以下がその部分のソースコードです。

 95
 96
 97
 98
 99
100
101
def before_validation
  self.section = self.section.tr('a-zA-Z1-9','a-zA-Z1-9').upcase unless self.section.blank?
end

def before_save
  self.crypted_password = encrypt(password) if password_required?
end

 95行目のbefore_validationというのが、コールバックの宣言文になっています。before_validationは、名前のとおりバリデーション処理の直前にRailsフレームワークから呼び出されて実行されます。

 96行目では、ユーザーの入力した大文字・小文字、全角・半角のぶれを統一する処理を記述していますが、この部分が、バリデーション前に実行されるのです。

 また、99行目のbefore_saveも同じコールバックの処理になりますが、呼び出されるタイミングがバリデーション後になります。この処理はユーザーのパスワードを暗号化している処理で、コールバックを使うことで、いろいろな個所で行うのでなく1カ所で記述できるようになっています。

 ほかにも、“before_xxx”や“after_xxx”という形で、いろいろなタイミングで呼び戻されるようなコールバックの仕組みが用意されています。

 ちなみに、コールバックを使うことで最初に思い付くのは、データベースへの更新日時を記録することだと思います。これについては、非常によく行われるということで、ActiveRecordの基本機能として最初から実装されています。

 その使い方は、保存したいテーブルに、update_atというカラム名を定義しておくというものです。これで、データの更新が掛かった際に、自動的にそのタイミングの時刻が保存されるようになります。ほかにもcreate_atなどがあります。

3/4

Index
ActiveRecordを使ったソースコードを読もう
  Page1
SKIPバージョン1.0リリース!
MVCモデルのM
  Page2
データの検索
データの更新
Page3
値の検証(バリデーション)
コールバック
  Page4
テーブルの関連
トランザクション

Railsコードリーディング 〜scaffoldのその先へ〜

 Ruby/Rails関連記事
プログラミングは人生だ
まつもと ゆきひろのコーディング天国
 ときにプログラミングはスポーツであり、ときにプログラミングは創造である。楽しいプログラミングは人生をより実りあるものにしてくれる
生産性を向上させるRuby向け統合開発環境カタログ
Ruby on Rails 2.0も強力サポート
 生産性が高いと評判のプログラミング言語「Ruby」。統合開発環境を整えることで、さらに効率的なプログラミングが可能になる
かんたんAjax開発をするためのRailsの基礎知識
Ruby on RailsのRJSでかんたんAjax開発(前編)
 実はAjaxアプリケーション開発はあなたが思うよりも簡単です。まずはRuby on Railsの基礎知識から学びましょう
Praggerとnetpbmで作る画像→AA変換ツール
Rubyを使って何か面白いものを作ってみよう!
 一般的な画像をアスキーアートに変換するツールを作ってみる。さらに出力にバリエーションを持たせてみよう
コードリーディングを始めよう
Railsコードリーディング〜scaffoldのその先へ〜(1)
 優れたプログラマはコードを書くのと同じくらい、読みこなす。優れたコードを読むことで自身のスキルも上達するのだ
  Coding Edgeフォーラムフィード  2.01.00.91


Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

>

Coding Edge 記事ランキング

本日 月間