Rails ActiveRecordで値が変更する前後の値を取得する
ActiveRecordで値が変更する前後の値を取得することがあったのでメモ
Rails 2.1あたりからActiveRecordの変更前後の値を取得する機能が備わっている。
method | 意味 |
---|---|
changed? | 変更されているかどうか |
changed | 変更されているattribute名の配列 |
changeds | 変更されているattribute名と値のハッシュ。値は変更前後の値を配列で。 |
{attr}_changed? | {attr}が変更されているかどうかの判定 |
{attr}_was | {attr}の変更前の値。変更されていない場合は元の値 |
{attr}_change | {attr}の変更前後の値の配列。変更されていなかったらnil |
{attr}_will_change! | {attr}を変更することを明示。 |
attrには属性名が入ります。nameの場合 name_wasで変更前の値を取得することができる
使用例
Railsのコールバック処理で複数の配列データを1つに統一したい場合に利用する
コールバック処理
- before_save
- before_update
- after_update
etc...
before_update処理でmerge_tagメソッドを実行する
merge_tagメソッドでは既に登録されていた既存の値(tag)と、
変更が加えられた新規の値tag_wasを組み合わせる(merge)処理が行われ、
self.tagに代入される
before_update :merge_tag def merge_tag # tag_wasには元々のtagの値が入り、 # mergeの引数のtagは新たなtagの値になる self.tag = tag_was.merge(tag) end
もっと簡単な例で動きを説明すると
tag = Tag.find(1) #=> #<Tag:0x007fc35ee6fc98 id: 1, name: "ドラえもん", created_at: Wed, 11 Apr 2016 20:21:02 JST +09:00> tag.name #=> "ドラえもん" tag.changed? #=> false tag.name = "のび太" #=> "のび太" tag.changed? #=> true tag.name_was #=> "ドラえもん"
のように、tag.name_wasで変更前の値を取得することができています。
ActiveRecordのちょっとした機能ですが、応用的な処理を実装する時には便利に使えるかなと思います。