Rails でトランザクション完了後に更新内容を取得する #rails

概要

トランザクションとは分離したいが、保存した内容によって事後処理を行いたい場合がある。

changed?hoge_changed? あたりは save 後には false になってしまうため、更新内容を取得できない。

ApplicationRecord.transaction do
  if foo.name_changed?
    # ここでは変更を検知できるけど
  end

  foo.save!
  bar.save!
end

if foo.name_changed?
  # ここでは変更を検知できない
end

対応

hoge_previously_changed? を使うと、変更内容を取得できる。

ApplicationRecord.transaction do
  foo.save!
  bar.save!
end

if foo.name_previously_changed??
  # 変更を検知できる!
end

変更前後の値を比較したり、変更内容を判定したり、まとめて変更を取得できたりもする。

foo.previous_changes         # => {"name" => [nil, "Bill"]}
foo.name_previously_changed? # => true
foo.name_previously_changed?(from: nil, to: "Bill") # => true
foo.name_previous_change     # => [nil, "Bill"]
foo.name_previously_was      # => nil

また ID の変更を判定することで、「新規作成か更新か」を区別するという応用もできる。

# true なら新規作成
foo.id_previously_changed?

詳細はドキュメントを参照。

api.rubyonrails.org

その他

今回のケースでは関係なかったが、 persisted? というのもあった。

どこかで役に立ちそう。

railsdoc.com

参考