You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:18:47