RailsのActiveRecordでカラムの変更前後の情報を取得

# はじめに
ActiveRecordで{attr_name}\_wasのメソッドをコールバック時に利用してみたので、せっかくだったらと思い以下のメソッド全部の実行結果をまとめてみる。

- changed?
- changed
- changes
- {attr\_name}\_changed?
- {attr\_name}\_was
- {attr\_name}\_change

※この子だけ使う機会がよく分からないので割愛します!

- {attr\_name}\_will_change!

メソッド詳しく知りたい方は以下のリンクからソースコードどうぞ
[rails/activemodel/lib/active_model/dirty.rb](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/dirty.rb)

# 目的
以下のコールバック時での各メソッドの実行結果を確認する

- before_save
- after_save
- after_commit

# 試した内容

色々試すように適当なtestモデル作成

```rb:app/models/test.rb
# == Schema Information
#
# Table name: tests
#
#  id                     :integer          not null, primary key
#  score                  :integer          not null
#  grade                  :text(65535)      not null
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
#

class Test < ActiveRecord::Base
  before_save  TestCallbacks.new
  after_save   TestCallbacks.new
  after_commit TestCallbacks.new
end
```

コールバックはあえて分けて用意(理由は特にない
全てのタイミングでbinding.pryを差し込んでみる

```rb:app/models/test_callbacks.rb
class TestCallbacks
  def before_save(test)
    binding.pry
  end

  def after_save(test)
    binding.pry
  end

  def after_commit(test)
    binding.pry
  end
end
```

以下のようなテストデータ用意してgradeカラムを更新

```rb
pry(main)> test = Test.first
+----+-------+-------+---------------------------+---------------------------+
| id | score | grade | created_at                | updated_at                |
+----+-------+-------+---------------------------+---------------------------+
| 1  | 80    | C     | 2016-03-03 18:05:55 +0900 | 2016-03-03 18:05:55 +0900 |
+----+-------+-------+---------------------------+---------------------------+
pry(main)> test.update(grade: 'B')
```

## before_saveのタイミングでの結果
```rb
[7] pry(#<TestCallbacks>)> test.grade
"B"
[8] pry(#<TestCallbacks>)> test.changed?
true
[9] pry(#<TestCallbacks>)> test.changed
[
    [0] "grade"
]
[10] pry(#<TestCallbacks>)> test.changes
{
    "grade" => [
        [0] "C",
        [1] "B"
    ]
}
[11] pry(#<TestCallbacks>)> test.grade_changed?
true
[12] pry(#<TestCallbacks>)> test.score_changed?
false
[13] pry(#<TestCallbacks>)> test.grade_was
"C"
[14] pry(#<TestCallbacks>)> test.grade_change
[
    [0] "C",
    [1] "B"
]
```

## after_saveのタイミングでの結果
※updated_atカラムが更新されようとしている以外は変わらない

```rb
pry(#<TestCallbacks>)> test.grade
"B"
pry(#<TestCallbacks>)> test.changed?
true
pry(#<TestCallbacks>)> test.changed
[
    [0] "grade",
    [1] "updated_at"
]
pry(#<TestCallbacks>)> test.changes
{
         "grade" => [
        [0] "C",
        [1] "B"
    ],
    "updated_at" => [
        [0] Thu, 03 Mar 2016 18:05:55 JST +09:00,
        [1] Thu, 03 Mar 2016 19:03:51 JST +09:00
    ]
}
pry(#<TestCallbacks>)> test.grade_changed?
true
pry(#<TestCallbacks>)> test.score_changed?
false
pry(#<TestCallbacks>)> test.grade_was
"C"
pry(#<TestCallbacks>)> test.grade_change
[
    [0] "C",
    [1] "B"
]
```

## after_commitのタイミングでの結果

```rb
pry(#<TestCallbacks>)> test.grade
"B"
pry(#<TestCallbacks>)> test.changed?
false
pry(#<TestCallbacks>)> test.changed
[]
pry(#<TestCallbacks>)> test.changes
{}
pry(#<TestCallbacks>)> test.grade_changed?
false
pry(#<TestCallbacks>)> test.grade_was
"B"
pry(#<TestCallbacks>)> test.grade_change
nil
```

# まとめ
* `{attr_name}_was`のようなメソッドはデータの更新完了後は変更前のデータ取れませんが、after_saveのタイミングであれば変更前のデータ取れるので何かと使えるタイミングが多いんじゃないかなと思いました
* この辺りのメソッドの面白い活用事例などありましたら教えていただきたいです
  - 特にこの子`{attr_name}_will_change!`