AWDwR "Chapter15 More Active Record"つづき

もっともっとActive Record!

Callbacks

Active Recordのライフサイクルのいろいろなイベントをフックできるよ。

新規レコード保存時のコールバック

before_validation
before_validation_on_create
after_validation
after_validation_on_create
before_save
before_create
after_create
after_save

レコード更新時のコールバック

before_validation
before_validation_on_update
after_validation
after_validation_on_update
before_save
before_update
after_update
after_save

レコード削除時のコールバック

before_destroy
after_destroy

それ以外にfind操作後のafter_find、新規モデルオブジェクト生成後のafter_initializeがあるんだけど、この2つだけはハンドラじゃなくてメソッドで定義すること。ハンドラで書いても無視されちゃうよ。

それから、テーブルにcreated_at, created_on, updated_at, updated_onというカラムがあればそれぞれ自動的に生成時の時刻、日付、更新時の時刻、日付をセットしてくれる。またコールバックハンドラを別クラスに定義したり、オブザーバを定義したりできるよ。

class Order < ActiveRecord::Base
  before_validation :CreditCardCallbacks.new # コールバッククラス
end

オブザーバクラス
class OrderObserver < ActiveRecord::Observer
end

Miscellany

==はidが等しいかどうかで判定しているんだけど、保存前のモデルオブジェクトはidが正しく設定されていないので正しく判定されない。保存前のオブジェクトに==を使いたい場合は==をオーバライドしてね。

それから直接SQL文を発行したい場合は

result = Order.connection.select_all("select id, name from orders")

というような感じでできる。ただしidをちゃんとフェッチしておかないと、その後でsaveを呼んでもDBに保存してくれないので注意。


マジックカラム名のまとめ

created_at,created_on,updated_at,updated_on
生成時刻、更新時刻
lock_version
楽観的ロックのバージョン番号
type
単一テーブル継承のタイプ名
id
プライマリキー
xxx_id
外部キー
xxx_count
カウンタキャッシュ
position
acts_as_listのリストの位置
parent_id
acts_as_treeの親のid


以上、もっとActive Record!でした。