active_recordのattributeメソッドまとめ
ちょっと使う機会があったのでまとめ。 変更前後で値がとれるのは便利。
こういうモデルがあったとする。
user = User.first => #<User id: 1, firstname: "花子", lastname: "山田", firstname_phonetic: "ハナコ", lastname_phonetic: "ヤマダ", email: "test@example.com">
保存前に使うメソッド
changes_to_save
変更されている値の検知を行う
user.changes => {} user.lastname = "鈴木" user.lastname_phonetic = "スズキ" user.changes => {"lastname"=>["山田", "鈴木"], "lastname_phonetic" => ["ヤマダ", "スズキ"]} # { 変更したカラム名のキー => [変更前の値, 変更後の値], ... }
attribute_change_to_be_saved(attr_name)
指定したカラムの変更前後の値を返す
user.attribute_change_to_be_saved("lastname") => nil user.lastname = "鈴木" user.attribute_change_to_be_saved("lastname") => ["山田", "鈴木"]
has_changes_to_save?
変更を検知して true / falseを返す
user.has_changes_to_save? => false user.lastname = "鈴木" user.lastname_phonetic = "スズキ" user.has_changes_to_save? => true
changed_attribute_names_to_save
変更されるカラム名を配列で返す
user.changed_attribute_names_to_save => [] user.lastname = "鈴木" user.lastname_phonetic = "スズキ" user.changed_attribute_names_to_save => ["lastname", "lastname_phoneic"] # [変更したカラム名1, 変更したカラム名2]
attributes_in_database
変更される箇所のデータベース上の値を返す
user.attributes_in_database => {} user.lastname = "鈴木" user.lastname_phonetic = "スズキ" user.attributes_in_database => {"lastname"=>"山田", "lastname_phonetic"=>"ヤマダ"}
attribute_in_database(attr_name)
指定したカラムのデータベース上の値を返す(変更したかどうかは関係なし)
user.attribute_in_database("lastname") => "山田" user.lastname = "鈴木" user.attribute_in_database(:lastname) => "山田" # 指定はシンボルでも文字列でも可能
will_save_change_to_attribute?(attr_name, **options)
指定したカラムの変更に対して true / falseを返す
user.will_save_change_to_attribute?("lastname") => false user.lastname = "鈴木" user.will_save_change_to_attribute?("lastname") => true
また、オプションとしてfromとtoが使えます。
user.lastname = "鈴木" # fromは変更前の値が一致した時にtrue user.will_save_change_to_attribute?("lastname", from: "山田") => true user.will_save_change_to_attribute?("lastname", from: "吉田") => false # toは変更後の値が一致した時にtrue user.will_save_change_to_attribute?("lastname", to: "鈴木") => true user.will_save_change_to_attribute?("lastname", from: "吉田") => false # fromとtoを同時に渡すと変更前と変更後の値が一致した時にtrue user.will_save_change_to_attribute?("lastname", from: "山田", to: "鈴木") => true user.will_save_change_to_attribute?("lastname", from: "山田", to: "吉田") => false
設定Aから設定Bに変更した時に特定の処理を挟みたいとか、そういう感じの時に使えそうかな? (例は使い方悪いですね・・・笑)
保存後に使うメソッド
saved_change_to_attribute?(attr_name, **options)
指定したカラムが変更されていた場合 true/falseを返す
user.lastname = "鈴木" user.save user.saved_change_to_attribute?("lastname") => true
こちらもwill_save_change_to_attribute?メソッドと同様にfrom, toオプションが使えます。
saved_change_to_attribute(attr_name)
指定したカラムの変更前後の値を取得する
user.lastname = "鈴木" user.save user.saved_change_to_attribute("lastname") => ["山田", "鈴木"] # [変更前の値, 変更した値]
attribute_before_last_save("lastname")
指定したカラムの変更前の値を取得する
user.lastname = "鈴木" user.save user.attribute_before_last_save("lastname") => "山田"
saved_changes
変更した値を全て取得する
user.lastname = "鈴木" user.save user.saved_changes => {"lastname"=>["山田", "鈴木"], "updated_at"=>[Mon, 15 Apr 2019 12:36:00 JST +09:00, Thu, 25 Apr 2019 12:26:24 JST +09:00]} # { カラム名1 => [変更前の値, 変更後の値], カラム名2 => [変更前の値, 変更後の値], ... }
saved_changes?
変更があったら true / falseを返す
user.lastname = "鈴木" user.save user.saved_changes? => true