こんにちは、鈴木です。
ActiveRecord は使い勝手の良いライブラリです。
ActiveRecord::Base クラスを継承するだけで、ほとんど設定することなく、その恩恵に預かることができます。
今回は、そのありがたい恩恵の中から、属性に代入した値に関する部分をピックアップします。
具体的には、型変換前の値が取得できること、属性の変更前の値を知ることができることなどをご紹介します。
型変換前の値
例として User というモデルがあり、年齢を数値型で保持する age という属性があるとします。
Rails の ActiveRecord はデータベースにおけるカラムの型に応じて、代入された値を型変換してくれます。
例えば、数値型の age に "123" という文字列を代入したとします。
1 2 |
user = User.new user.age = "123" |
代入後に user.age を参照すると、数値に変換された値が返されます。
1 |
user.age # => 123 |
しかし、型変換される前の値を知る必要があるケースが少ないながらも存在します。
例えば、バリデーション処理で型変換前の値に対してフォーマットをチェックしたい場合などです。
そのような場合は、「属性名_before_type_cast」で型変換前の値を取得することができます。
1 |
user.age_before_type_cast # => "123" |
変更された属性
変更された属性を知ることもできます。
例として、ID=1 のユーザを find したらユーザ名が「たろう」だった、というところから始めます。
1 2 |
user = User.find(1) user.name # => "たろう" |
名前を「はなこ」に変更してみます。
1 |
user.name = "はなこ" |
名前を変更(新しい値を代入)しました。
つまり、user は変更されました。
オブジェクトが変更されたかどうかは、changed? メソッドで知ることができます。
1 |
user.changed? # => true |
属性ごとに変更されたかどうかを知りたい場合は「属性名_changed?」を使用します。
1 |
user.name_changed? # => true |
ところで、変更される前の値は何だったのでしょうか?
そんな時は、「属性名_was」を使用します。
1 |
user.name_was # => "たろう" |
name は何から何に変更されたのでしょうか?
というときには、「属性名_change」を使用します。
1 |
user.name_change # => ["たろう", "はなこ"] |
changes メソッドを使用すると、「どの属性の値が、何から何に変更されたのか」をまとめて知ることができます。
1 |
user.changes # => {"name"=>["たろう", "はなこ"]} |
ひとつだけ注意なのですが、String#<< メソッドなどで破壊的に値を変更した場合は、changed? は false を返しますのでご注意ください。
1 2 3 4 5 |
user = User.find(1) user.name # => "たろう" user.changed? # => false user.name << "二世" user.changed? # => false |
「属性名_will_change!」を呼び出すと、その属性は変更されたものとして扱われます。
1 2 |
user.name_will_change! user.changed? # => true |
ActiveRecord には、細かい便利機能が色々あります。
それらは簡潔なコードを書くための助けになってくれます。
Rails は生産性が高い、と言われることは多いです。
今回ご紹介したような地味ながらも便利な機能が盛りだくさんなところが、その根拠の一つではないでしょうか。