💬
ActiveRecord の #changes_to_save と #saved_changes
最近、よく使っているので ActiveRecord::Base#changes_to_save と #saved_changes の紹介。
名前の通りではあるんですがそれぞれ
-
#changes_to_save=> 保存前の変更内容 -
#saved_changes=> 保存後の変更内容
のような情報を取得することができます。
user = User.find_by(name: "homu")
pp user
# => #<User:0x000076769d6d3348 id: 1, name: "homu", email: nil, age: 14>
# レコードを取得した直後はどちらも空
pp user.changes_to_save # => {}
pp user.saved_changes # => {}
# レコードの内容を変更し、保存される前
# このときの変更内容は #changes_to_save で情報が取得できる
user.assign_attributes(name: "mami", email: "mami@example.com")
pp user.changes_to_save # => {"name" => ["homu", "mami"], "email" => [nil, "mami@example.com"]}
pp user.saved_changes # => {}
# レコードの内容を変更し、保存した後
# このときの保存された値は #saved_changes で情報が取得できる
user.save!
pp user.changes_to_save # => {}
pp user.saved_changes # => {"name" => ["homu", "mami"], "email" => [nil, "mami@example.com"]}
コールバックとかで保存前、保存後の状態をゴニョゴニョしたいときに便利ですね。
ちなみに似たようなメソッドで #changes もあるんですがこちらは #changes_to_save と同じような挙動になります。
vser = User.find_by(name: "homu")
pp user
# => #<User:0x000076769d6d3348 id: 1, name: "homu", email: nil, age: 14>
user.assign_attributes(name: "mami", email: "mami@example.com")
pp user.changes # => {"name" => ["homu", "mami"], "email" => [nil, "mami@example.com"]}
pp user.changes_to_save # => {"name" => ["homu", "mami"], "email" => [nil, "mami@example.com"]}
pp user.saved_changes # => {}
user.save!
pp user.changes # => {}
pp user.changes_to_save # => {}
pp user.saved_changes # => {"name" => ["homu", "mami"], "email" => [nil, "mami@example.com"]}
Discussion