如何在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
相关产品推荐
相关产品推荐

