如何在PaperTrail中结合元数据使用自定义版本表?
我来帮你梳理下如何正确用PaperTrail实现这个需求,你的思路方向是对的,但有几个细节需要调整,确保功能正常运行:
1. 修正Storage模型的PaperTrail配置
你当前的has_paper_trail调用参数格式有问题,需要把class_name和meta放在同一个哈希参数里,正确写法如下:
class Storage < ApplicationRecord has_paper_trail( class_name: 'StorageVersion', meta: { storage_type: :storage_type } ) # 其他业务方法... end
这里meta: { storage_type: :storage_type }的意思是,PaperTrail会把Storage实例的storage_type属性值存入版本记录的metaJSON字段中;如果你想要把storage_type作为单独的数据库字段存储,还需要额外处理,我后面会说明。
2. 正确定义StorageVersion模型
建议把模型文件直接放在app/models/storage_version.rb(不需要放在paper_trail子目录下,除非你有特殊命名空间需求),然后根据表结构调整代码:
class StorageVersion < PaperTrail::Version self.table_name = 'storage_versions' # 填写你的实际表名,通常就是storage_versions # 如果是把storage_type作为单独字段存储(而非存在meta里),添加回调自动赋值 after_initialize do self.storage_type = item&.storage_type if item.is_a?(Storage) end end
3. 确保数据库表结构正确
如果还没创建storage_versions表,需要生成迁移文件,除了PaperTrail默认的字段,别忘了加上storage_type字段:
class CreateStorageVersions < ActiveRecord::Migration[7.0] def change create_table :storage_versions do |t| t.string :item_type, null: false t.bigint :item_id, null: false t.string :event, null: false t.string :whodunnit t.jsonb :object t.jsonb :object_changes t.datetime :created_at t.string :storage_type # 新增的存储类型字段 t.index [:item_type, :item_id] end end end
执行迁移后,数据库表就具备存储storage_type的能力了。
4. 验证功能是否正常
启动 Rails 服务器后,修改任意一个Storage实例的属性,然后查询storage_versions表,你会看到新增的版本记录,其中storage_type字段(或者meta字段里的storage_type值)会正确对应原实例的存储类型。
内容的提问来源于stack exchange,提问作者Ayer
相关产品推荐
相关产品推荐

