おぴよの気まぐれ日記

おぴよの気まぐれ日記

岡山やプログラミング、ファッションのこと、子育てや人生、生き方についての備忘録。

【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処理で利用するようにしましょう!