はじめに
趣味として、RailsのReadmeやDocumentを読んでいる。そこで「へー」と思うのだけれども、すぐに忘れてしまうため記事としてしっかり研究したい。今回は、ActiveModel::Dirty
がクラスの監視の役割を持っているということを知った。
Rails
RailsのActiveRecord::Base
を継承しているモデルでは、そのインスタンス変数を監視することができる。具体的に例を見てゆく。
Dirty#changed?
Saveされるまでで、そのインスタンスの値が変わったかどうかで、true
もしくはfalse
を返す。
goku = Saiya.new
goku.changed? # 作成されたばかりのものはもちろん、falseを返す。
# 実際に変更を加えてみる
goku.name = "悟空"
goku.changed? # nameが変更されたのでtrue
これまではなんの驚きもない予測どおりな仕様である。では変更を加え、save
した直後は何を返すのか。
goku.save
goku.changed? # false を返す。
レコード(DBのテーブルに入っている値)と、現在のインスタンスの値の差ということかと思われます。save
が失敗すればchanged?
はtrue
を返します。同じ値を再代入しても、false
を返します。
goku.name = "カカロット"
goku.save
# => 失敗した時
goku.changed? # true
goku = Saiya.where(name: "悟空")
goku.name = "悟空"
goku.changed? # false
これはバリデーションのロジックを組む時に便利なメソッドですね。
ちなみに、特定の一つのレコードだけが変化したかどうかを確かめるためのメソッドも、Railsの方で用意してくれてます。
goku = Goku.new
goku.name = "悟空"
goku.changed? # true
goku.name_changed? # true
goku.power_changed? #false