如何仅在Papertrail的create事件中添加自定义meta数据?
解决PaperTrail仅在create事件添加指定meta数据的问题
问题场景
当前代码默认给所有版本记录添加object: 'custom_data'的meta字段:
has_paper_trail meta:{ object: 'custom_data' }
需求是仅在create事件生成版本时添加该meta字段,update和destroy事件正常生成版本但不附带这个meta。
之前尝试的两种写法均无效:
- 用
new_record?判断的lambda写法:
has_paper_trail meta: { object: ->{ instance.new_record? ? 'custom_data' : nil } }
- 用
on: [:create]限制事件的写法:
has_paper_trail on: [:create] meta:{ object: 'custom_data' }
可行实现方案
方案1:利用meta的lambda判断事件类型
PaperTrail的meta支持传入lambda,且lambda会接收当前实例作为参数,我们可以通过实例的paper_trail_event属性直接判断当前是哪个事件:
has_paper_trail meta: ->(instance) { { object: (instance.paper_trail_event == 'create' ? 'custom_data' : nil) } }
这样只有当事件为create时,meta里才会包含object: 'custom_data',update和destroy事件生成的版本不会有这个字段。
方案2:使用PaperTrail的版本回调
通过before_save_version回调,在版本保存前动态添加meta字段:
has_paper_trail before_save_version :add_create_only_meta private def add_create_only_meta(version) version.meta[:object] = 'custom_data' if version.event == 'create' end
这个方法更灵活,适合需要更复杂逻辑的场景,比如除了判断事件还需要额外条件的情况。
为什么之前的写法无效
- 第一种写法的问题:
new_record?的判断时机不准确,在create事件触发后,实例已经被保存,new_record?会返回false,导致lambda无法正确识别create事件;且lambda的写法有误,正确的meta lambda应该接收实例作为参数,而不是直接引用instance变量。 - 第二种写法的问题:
on: [:create]会让PaperTrail仅记录create事件的版本,update和destroy事件不会生成任何版本,违背了“正常记录update和destroy”的需求。
内容的提问来源于stack exchange,提问作者Harish Kumar
相关产品推荐
相关产品推荐

