PaperTrail手动版本控制异常:首次touch_with_version属性为nil
解决PaperTrail手动创建版本首次属性为nil的问题
我之前也遇到过类似的情况,当把PaperTrail的回调设置为on: []完全禁用自动版本后,第一次调用touch_with_version时确实会出现版本属性为空的问题,原因主要有两点:
- 首次调用时,模型实例从数据库加载后没有任何属性变更(
changed?返回false),PaperTrail无法捕获到需要记录的属性数据。 - 没有明确指定PaperTrail需要追踪的属性集合,导致即使触发版本创建,也不知道要保存哪些字段。
下面是几个可行的解决方案:
方案1:明确配置追踪属性并手动触发版本
首先在模型中指定要追踪的属性(可以用:all记录所有属性):
class MyModel < ApplicationRecord has_paper_trail on: [], tracked_attributes: :all end
然后在需要创建版本的地方,先确保模型有属性变更(比如touch),再手动调用版本保存方法:
model = MyModel.find(params[:id]) # 如果只是要更新updated_at并创建版本 model.touch # 手动保存版本,PaperTrail会自动记录当前所有属性 model.paper_trail.save_version(event: 'update')
方案2:手动构建版本数据
如果不想全局配置tracked_attributes,可以在创建版本时手动传入要保存的属性数据:
model = MyModel.find(params[:id]) model.touch # 手动创建版本,指定要存储的属性 model.paper_trail.create_version( event: 'update', object: model.attributes.to_yaml, # PaperTrail默认用YAML序列化属性 whodunnit: current_user&.id # 可选:记录操作人 )
方案3:强制标记属性为已变更
如果需要在模型没有实际变更的情况下创建版本(比如刚初始化的实例),可以手动标记属性为已变更,让PaperTrail捕获到:
model = MyModel.new(attr1: 'value1', attr2: 'value2') # 强制标记所有属性为已变更 model.changed_attributes.merge!(model.attributes) # 调用touch_with_version或者手动保存版本 model.paper_trail.touch_with_version
这样处理后,首次调用就能正确保存所有属性的版本数据了。
内容的提问来源于stack exchange,提问作者Abhinav Srivastava
相关产品推荐
相关产品推荐

