在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近开发需要,找到几个用来追踪ActiveRecord对象修改历史的方法,记录于此 ActiveRecord对象有不少关于change的方法 irb(main):099:0> ActiveRecord::Base.public_instance_methods.grep(/change/) 我认为重要的方法: 第一组方法,只反映属性修改后 且未曾保存到数据库时的状态 changed? 对象整体是否改变 attribute_changed? 指定属性是否改变 changed 返回有改变的属性名数组 => ["note"] changes 返回有改变的属性的hash对象 => {"note"=>["abd", "abe"]} attribute_was 指定属性修改前的值
第二组方法,反映属性修改且已经保存到数据库后的状态 saved_changes? 对象整体是否有过改变 previous_changes 有过改变的属性的hash对象 saved_changes 同 previous_changes attribute_previously_changed? 指定属性是否有已保存到数据库的改变 attribute_before_last_save 指定属性上次修改前的值
通过给每个属性赋新值对ActiveRecord对象进行修改的情况,可以再save之前使用第一组方法获知修改情况 # 获取数据对象 irb(main):020:0> d = Notice.find(13) # 查看原属性 irb(main):020:0> d.note => "" # 修改属性,然后再保存 change, and save irb(main):026:0> d.note='abc' => "abc" irb(main):027:0> d.attribute_was :note => "" irb(main):028:0> d.note => "abc" irb(main):028:0> d.changed?
irb(main):029:0> d.save => true irb(main):030:0> d.note => "abc" irb(main):031:0> d.attribute_was :note => "abc" irb(main):032:0> d.attribute_previously_changed? :note => true irb(main):033:0> d.attribute_before_last_save :note => "" irb(main):034:0> irb(main):034:0> d.changed? 直接调用update对ActiveRecord对象进行修改的情况,由于数据已经保存了,只能使用第二组方法获知修改情况 # 重新获取数据对象 irb(main):020:0> d = Notice.find(13) # 查看原属性 irb(main):020:0> d.note => "abc" # 直接更新数据 update directly irb(main):020:0> d.update! note: 'abd' (0.2ms) begin transaction (89.1ms) commit transaction => true irb(main):023:0> d.attribute_changed? :note => false irb(main):022:0> d.attribute_previously_changed? :note => true irb(main):021:0> d.attribute_before_last_save :note => "abc" irb(main):024:0> d.note => "abd" irb(main):025:0> d.attribute_was :note => "abd" 取得新的ActiveRecord对象,不能追踪属性变化,说明修改信息仅位于内存对象中
# 新的ActiveRecord对象,不能追踪,说明修改信息仅仅位于内存对象中 irb(main):037:0> d2 = Notice.find(13) Notice Load (0.2ms) irb(main):039:0> d2.note => "abd" irb(main):040:0> d2.attribute_previously_changed? :note => false irb(main):041:0> d2.attribute_before_last_save :note => nil irb(main):041:0>
# 遍历修改的属性 irb(main):044:0> (d.attribute_names - ["updated_at","created_at"]).each{|f| puts "#{f} chaned from [#{d.attribute_before_last_save(f)}] to [#{d[f]}]" if d.attribute_previously_changed?(f)} note chaned from [abc] to [abd]
# ActiveRecord对象的方法previous_changes获取修改的属性 hash, 包含原值和新值 irb(main):079:0> d.changes => {} irb(main):078:0> cs=d.previous_changes => {"note"=>["abc", "abd"], "updated_at"=>[Thu, 12 Nov 2020 15:18:07 CST +08:00, Thu, 12 Nov 2020 16:21:45 CST +08:00]} # 删除无用属性 irb(main):080:0> cs.delete :updated_at => [Thu, 12 Nov 2020 15:18:07 CST +08:00, Thu, 12 Nov 2020 16:21:45 CST +08:00] irb(main):081:0> cs => {"note"=>["abc", "abd"]}
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论