如何为ActiveAdmin评论添加加密?支持按资源类型限定
解决ActiveAdmin评论内容加密(支持特定资源类型)
为什么你的猴子补丁没生效?
你写的补丁里类名写错了——ActiveAdmin的评论模型是**ActiveAdmin::Comment(单数)**,对应的数据库表才是active_admin_comments(复数),所以之前的代码根本没作用到正确的类上。另外直接写模块嵌套的方式可能遇到加载顺序问题,导致补丁在类初始化后才执行,没生效。
方案1:全局加密所有评论内容
如果需要给所有ActiveAdmin评论加密,在config/initializers/下新建active_admin_comments_encryption.rb,写入以下代码:
ActiveSupport.on_load(:active_record) do # 确保ActiveAdmin::Comment类加载后再应用补丁 next unless defined?(ActiveAdmin::Comment) ActiveAdmin::Comment.class_eval do # 使用Rails 7原生模型加密加密body字段 encrypts :body end end
重启服务后,新创建的评论内容就会自动加密存储到数据库,读取时自动解密显示。
方案2:仅对特定资源类型的评论加密
如果只需要给指定模型(比如Order、Invoice)的评论加密,用条件式的存取器覆盖实现:
# config/initializers/active_admin_comments_encryption.rb ActiveSupport.on_load(:active_record) do next unless defined?(ActiveAdmin::Comment) ActiveAdmin::Comment.class_eval do # 定义需要加密的资源类型列表,替换成你的目标模型名 ENCRYPTED_RESOURCE_TYPES = ["Order", "Invoice"] # 覆盖body读取方法,仅指定资源类型解密 def body raw_body = super return raw_body unless ENCRYPTED_RESOURCE_TYPES.include?(resource_type) && raw_body.present? ActiveRecord::Encryption.decrypt(raw_body) end # 覆盖body赋值方法,仅指定资源类型加密 def body=(value) if ENCRYPTED_RESOURCE_TYPES.include?(resource_type) && value.present? super(ActiveRecord::Encryption.encrypt(value)) else super(value) end end end end
这个方案会自动识别评论关联的resource_type,只有在列表内的模型评论才会加密,其他评论保持明文存储,完全符合SOX合规的针对性加密要求。
注意事项
- 确保你已经正确配置了Rails 7的模型加密:
config/credentials.yml.enc已生成,且加密密钥配置正常(默认Rails 7新建项目会自动配置)。 - 已存在的明文评论不会自动加密,只有新创建或更新的评论会应用加密逻辑;如果需要加密历史数据,可以写批量更新脚本处理。
内容的提问来源于stack exchange,提问作者Jonathon Nordquist
相关产品推荐
相关产品推荐

