Help us understand the problem. What is going on with this article?

Rails 5.1 で attribute_was, attribute_change, attribute_changed?, changed?, changed 等が DEPRECATION WARNING

何が起きたか?

Rails 5.1 へアップデートして大量に DEPRECATION WARNING や spec エラーが起きたので、調べてみると Rails 5.1 で ActiveRecord::AttributeMethods::Dirty の

  • attribute_was
  • attribute_change
  • attribute_changed?
  • changed?
  • changed

辺りが非推奨になったらしいです。
参考: https://github.com/rails/rails/blob/master/activerecord%2Flib%2Factive_record%2Fattribute_methods%2Fdirty.rb#L213-L236

何故それらが非推奨になったか

Rails の開発者が changed 系のバグ報告を良く受けるらしい。動作的に分かりづらい部分もあるが、 Rails が提供しているメソッドとしても attribute_change の様なメソッドで、メソッド名もアレなのと、どのタイミングでどんな値が入るのか正しく理解しないと利用することが出来ない。 (自分も結構このへんは悩んだ記憶がある。)

かなり大きな破壊的な変更にはなるが、移行パスはシンプルなようです。コードベースから改善し API をより直感的にすることによりそれらを改善しようとしたのがこの変更のようです。

自分も正しく理解できているか不安だし、結構想像で書いている部分もあるので、詳しくは下記 PR を。
https://github.com/rails/rails/pull/25337

移行

移行作業は理解さえ出来ればシンプルですが、単純な機械的な置換作業をすると大怪我をします。書き換える場所が save 前なのか、save 後なのかを意識して書き換える必要があります。正しくは after_create/after_update より前か後かを意識すれば良いようです。
(https://github.com/rails/rails/blame/master/activerecord/lib/active_record/attribute_methods/dirty.rb#L19-L20)

変換表

表中の各 attribute はカラム名に置き換えて hoge というカラムで will_save_change_to_attribute? を使いたければ will_save_change_to_hoge? と読み替えてもらえると。

after_create/after_update より前の場合

修正前 修正後
attribute_changed? will_save_change_to_attribute?
attribute_change attribute_change_to_be_saved
attribute_was attribute_in_database
changes changes_to_save
changed? has_changes_to_save?
changed changed_attribute_names_to_save
changed_attributes attributes_in_database

after_create/after_update より後の場合

修正前 修正後
attribute_changed? saved_change_to_attribute?
attribute_change saved_change_to_attribute
attribute_was attribute_before_last_save
changes saved_changes
changed? saved_changes?
changed saved_changes.keys
changed_attributes saved_changes.transform_values(&:first)

嬉しいこと

after_create/after_update より後の場合 で書いているメソッドは callback が終わった後でも使えます。今まで save 後に record.changes が取得できなかったのが、 record.saved_changes をすれば前回の変更で何が変更されたかが取得できます。

と言っても、私の書いていたアプリではコレに該当する部分はありませんでしたが、、きっと嬉しい人はいるはず!

最後に

色んな所で似たような記事を見ましたが、正しくどのように対応すれば良いのかがイマイチまとまっていないものも多かったので、自分なりにまとめてみたつもりです。

ツッコミ・修正大歓迎です!

htz
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした