Rails 2.1・その5(model の値変更を覚えている)
-------------------------------------------
モデルの値を変更した後、セーブする前に、実際に変更したかどーだかなどという情報を参照できます。
↓いきなりまとめ
changed? :モデルの値を変更したかどうか
[カラム名]_changed? :モデルの指定したカラム名の値を変更したかどうか
[カラム名]_was :モデルの指定したカラム名の変更前の値
[カラム名]_change :モデルの指定したカラム名の変更前と後の値
changed :モデルの変更したカラム名のリスト
changes :モデルの変更したカラム名のリストと、変更前と後の値
[カラム名]_will_change! :モデルの指定したカラムの値を、= 以外の手段で変える場合に必要
例を使うと分かりやすいですね。
p = Person.first
p.name # => "yasushi"
p.changed? # => false
# もともと入っていた値と同じ値を入れても変更扱いにならない
p.name = "yasushi"
p.changed? # => false
# もともと入っていた値と違う値を入れると変更扱いになる
p.name = "kiyoshi"
p.changed? # => true
p.name_changed? # => true
p.age_changed? # => false
p.name_was # => "kiyoshi"
p.name_change # => ["kiyoshi", "yasushi"]
p.age_change # => nil
# さらに age カラムの値も変える
p.age # => 49
p.age += 1 # => 50
p.changed # => ["name", "age"]
p.changes # => {"name"=>["kiyoshi", "yasushi"], "age"=>[49, 50]}
# 注:↓のやり方だと = で値を代入していないので、変更扱いになりません!!
p = Person.first
p.name # => "kiyoshi"
p.name.replace("yasushi")
p.changed? # => false
p.save # DBの値は更新されない
# なのでこの場合は、[カラム名]_will_change! を使います
p = Person.first
p.name_will_change!
p.name # => "kiyoshi"
p.name.replace("yasushi")
p.changed? # => true
p.save # DBの値が更新される
お・ま・け!
唐突なダンキチ&ナヲミのおまけコーナーですが、↑の例で p.save をすると、変更していないカラムにも update が走りますが、変更したカラムだけ udpate を走らせたい場合
config/initializers ディレクトリにテキトーな名前のファイルを作って
ActiveRecord::Base.partial_updates = true
を書きます。
参考ブログ
Living on the edge (of Rails) #14 - the extreme edition. Extremely late.
What's New in Edge Rails: Dirty Objects
Tracking Attribute Changes
【広告】