ActiveRecordのDirty系小ネタ
環境
$ bin/rails -v
Rails 5.2.2
使い方例
今回はUserにnameというカラムがあるという形の例で説明
ActiveRecordでオブジェクトを作る、この時点ではsaveされてないのでnil。
u = User.new(name:"Taro") #=> #<User id: nil, name: "Taro", created_at: nil, updated_at: nil> u.name # => "Taro" u.name_before_last_save #=> nil
save処理を行う、これを行うとsaveされるが以前のものは無いのでnil
u.save (0.2ms) BEGIN User Create (1.0ms) INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('Taro', '2019-03-23 02:25:16', '2019-03-23 02:25:16') (19.7ms) COMMIT # => true u.name #=> "Taro" u.name_before_last_save #=> nil
saveすると、以前の値を取ることができる
u.name = "Ziro" #=> "Ziro" u.name #=> "Ziro" u.name_before_last_save # => nil u.save (0.2ms) BEGIN User Update (20.0ms) UPDATE `users` SET `name` = 'Ziro', `updated_at` = '2019-03-23 02:25:41' WHERE `users`.`id` = 13 (19.8ms) COMMIT #=> true u.name_before_last_save #=> "Taro"
当たり前ですが、新たに引き直した場合は取れない
# idが13のものは先程のレコードなので直指定で取得 new_read_u = User.find(13) User Load (23.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 13 LIMIT 1 # => #<User id: 13, name: "Ziro", created_at: "2019-03-23 02:25:16", updated_at: "2019-03-23 02:25:41"> new_read_u.name_before_last_save # => nil
注意点
似たようなものに{{カラム名}}_wasがあるが、振る舞いが違うので気をつける。
u.name # => "Ziro" u.name = "Saburo" # => "Saburo" # Saburoに変える前はZiroなのでZiro u.name_was # => "Ziro" u.name_before_last_save # => "Taro" # Saburoは保存されていないのでwasはZiroのまま u.name = "Shiro" # => "Shiro" u.name_was # => "Ziro" u.name_before_last_save # => "Taro"