ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

ruby rails ActiveRecord对象 的修改痕迹追踪

2020-11-13 09:00:36  阅读:313  来源: 互联网

标签:ActiveRecord changed rails note changes attribute irb main ruby


最近开发需要,找到几个用来追踪ActiveRecord对象修改历史的方法,记录于此

ActiveRecord对象有不少关于change的方法

irb(main):099:0>  ActiveRecord::Base.public_instance_methods.grep(/change/)
[:attachment_changes, :changed_for_autosave?, :saved_change_to_attribute, :saved_changes?, :saved_changes, :will_save_change_to_attribute?,
:attribute_change_to_be_saved, :changes_to_save, :changed_attribute_names_to_save, :has_changes_to_save?, :saved_change_to_attribute?, :attribute_changed_in_place?,
:changed, :clear_attribute_changes, :changes_applied, :attribute_changed?, :attribute_previously_changed?, :clear_changes_information, :changed_attributes,
:changed?, :previous_changes, :changes]

我认为重要的方法:

第一组方法,只反映属性修改后 且未曾保存到数据库时的状态

changed?   对象整体是否改变

attribute_changed?   指定属性是否改变

changes 改变属性的hash对象

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?
=> true
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?
  => false
  irb(main):034:0> d.attribute_previously_changed? :note
  => true

直接调用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]

使用previous_changes获取修改过的那些属性的 hash, 包含原值和新值
# 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"]}

 

标签:ActiveRecord,changed,rails,note,changes,attribute,irb,main,ruby
来源: https://www.cnblogs.com/dajianshi/p/13967475.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有