如何在保存前获取完整旧记录?替代Person_was的实现方案
获取Active Record保存前的完整旧记录
要实现类似你说的Person_was这种获取整条完整旧记录的功能,有以下几种实用方案:
方案1:通过回调缓存修改前的完整记录
在你的模型中添加回调,提前缓存未修改的记录副本:
class Person < ApplicationRecord attr_reader :original_record before_save :cache_original_record private def cache_original_record # 复制当前对象的原始属性并冻结,避免后续修改影响缓存的旧记录 @original_record = self.class.new(self.attributes).tap(&:freeze) end end
之后在保存前的任何时机,都可以通过person.original_record拿到完整的旧记录,所有字段都是修改前的状态,而且冻结后的对象不会被意外篡改。
方案2:直接从数据库重新查询原始记录
如果不需要额外缓存,也可以直接查询数据库获取当前记录的原始状态:
original_person = Person.find(self.id)
注意:这种方法拿到的是数据库里的最新值,如果当前请求周期外有其他操作修改了这条记录,会和当前对象修改前的状态不一致,适合低并发或无外部修改的场景。
方案3:利用previous_changes还原旧记录
通过Active Record提供的previous_changes方法,结合当前属性还原出旧记录:
# 合并当前属性与所有修改字段的旧值 original_attrs = self.attributes.merge( self.previous_changes.transform_values { |old_val, _| old_val } ) # 生成旧记录实例 original_person = Person.new(original_attrs) original_person.id = self.id # 确保ID与原记录一致
这种方法不需要额外回调,适合临时生成旧记录的场景,能准确还原当前对象修改前的所有字段状态。
内容的提问来源于stack exchange,提问作者Noam B.
相关产品推荐
相关产品推荐

