【Rails】モデルの変更前後の値や変更されたのかをチェックする
Ruby on Railsで保存や変更した時の値を取得したり、値が変更されたのかどうかをチェックする方法を紹介します。
変更のチェック(changed?)
モデル全体で変更があるかどうかをチェックするにはchanged?
を使います。
> hoge = Hoge.last Hoge Load (0.3ms) SELECT "hoges".* FROM "hoges" ORDER BY "hoges"."id" DESC LIMIT $1 [["LIMIT", 1]] => #<Hoge:0x00007fd646062b78 id: 1, name: "opiyo", age: 30, gender: nil, birthday: Fri, 04 Aug 1989, email: nil, created_at: Mon, 30 Sep 2019 20:47:43 JST +09:00, updated_at: Mon, 30 Sep 2019 20:47:43 JST +09:00> > hoge.name = 'opiyoopiyo' => "opiyoopiyo" > hoge.changed? => true
特定のカラムの変更をチェック(column_changed?)
特定のカラムのみが変更されたかどうかをチェックするにはchanged?の前にカラム名を付けてカラム名_changed?
にします。
> hoge = Hoge.last => #<Hoge:0x00007fd646062b78 id: 1, name: "opiyo", age: 30, gender: nil, birthday: Fri, 04 Aug 1989, email: nil, created_at: Mon, 30 Sep 2019 20:47:43 JST +09:00, updated_at: Mon, 30 Sep 2019 20:47:43 JST +09:00> > hoge.name = 'opiyoopiyo' => "opiyoopiyo" > hoge.name_changed? => true # ageは変更してないので`false`になる > hoge.age_changed? => false
変更前の値を取得する(column_was)
変更前の値についてはカラム名の後に_was
を付けます。
> hoge.name => "opiyo" > hoge.name = 'opiyoopiyo' => "opiyoopiyo" > hoge.name_was => "opiyo"
使い方と注意点
利用する場面としてはbefore_save
が多いでしょうか。
# hoge.rb class Hoge < ApplicationRecord before_save :adult?, if: Proc.new { self.birthday_changed? } def adult? self.age > 20 end end
最大の注意点としてはafter_save
などのafter
処理で利用すると正しく取得できないので、必ずbefore
処理で利用するようにしましょう!