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

如何在PaperTrail中展示Rails枚举的键而非整数值?

解决方案

你可以通过两种方式实现将枚举的键(而非整数)用于变更记录的保存或展示:

1. 保存时直接记录枚举键(推荐新记录使用)

重写模型里的paper_trail_object_changes方法,让PaperTrail在保存版本时自动把枚举整数转换为对应的键:

class Article < ApplicationRecord
  has_paper_trail
  enum status: { draft: 0, published: 1 }

  def paper_trail_object_changes
    # 获取默认的变更数据
    changes = super
    # 针对status枚举转换值为键
    if changes.key?(:status)
      changes[:status] = changes[:status].map { |val| statuses.key(val) }
    end
    changes
  end
end

如果项目里有多个带枚举的模型,可以把逻辑抽成通用的Concern,避免重复代码:

# app/models/concerns/paper_trail_enum_handler.rb
module PaperTrailEnumHandler
  extend ActiveSupport::Concern

  included do
    def paper_trail_object_changes
      changes = super
      # 遍历模型所有枚举,自动转换
      self.class.enums.each do |enum_name, enum_map|
        if changes.key?(enum_name)
          changes[enum_name] = changes[enum_name].map { |val| enum_map.key(val) }
        end
      end
      changes
    end
  end
end

然后在需要的模型里引入:

class Article < ApplicationRecord
  has_paper_trail
  include PaperTrailEnumHandler
  enum status: { draft: 0, published: 1 }
end

2. 仅在展示时转换(兼容历史记录)

如果不想修改已保存的历史版本数据,只在前端展示时把整数转成枚举键,可以在版本模型(Version)里添加格式化方法:

class Version < PaperTrail::Version
  def formatted_object_changes
    changes = object_changes.deep_dup
    # 针对Article的status枚举转换,其他模型同理扩展
    if changes["status"]
      changes["status"] = changes["status"].map { |val| Article.statuses.key(val.to_i) }
    end
    changes
  end
end

之后在展示变更的视图里,调用version.formatted_object_changes替代原有的version.object_changes即可。

注意:第一种方法只对修改后的新生成的版本记录生效,历史记录还是会保留整数;第二种方法可以兼容所有新老记录,但需要在展示层做处理。

内容的提问来源于stack exchange,提问作者Samar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:25:10