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

如何让Ruby Rails的attr_encrypted属性直接返回Money对象?

解决attr_encrypted加密属性直接返回Money对象的问题

我之前也遇到过一模一样的需求,其实最直接有效的方案就是重写attr_encrypted自动生成的getter方法,既不用额外加辅助方法,还能轻松拿到当前用户的currency字段。

具体实现代码

class User < ApplicationRecord
  attr_encrypted :balance, key: 'some super secret key'

  # 重写balance getter,直接返回Money对象
  def balance
    # 调用attr_encrypted生成的原始getter,获取解密后的数值
    raw_decrypted_balance = super
    # 结合当前用户的currency生成Money对象,同时处理nil场景
    raw_decrypted_balance.present? ? Money.new(raw_decrypted_balance, currency) : nil
  end
end

为什么这个方案能解决问题?

  • attr_encrypted在定义attr_encrypted :balance后,会自动生成一个balance方法,负责解密并返回原始数值。我们通过super调用这个原始方法,就能拿到解密后的余额。
  • 重写的balance是实例方法,能直接访问当前User实例的currency属性,完美解决了你之前用marshaler时无法获取用户币种的痛点。

为什么之前的Marshaler方案行不通?

你尝试的自定义Marshaler是全局模块,它的load方法无法访问到具体的User实例,自然拿不到该用户的currency字段,这个思路从根源上就没法满足需求。

可选优化

如果希望nil值也返回一个有效的Money对象,可以调整代码:

def balance
  raw_decrypted_balance = super || 0
  Money.new(raw_decrypted_balance, currency)
end

这样不管balance是否为空,都会返回一个合法的Money对象,避免后续逻辑出现空指针问题。

内容的提问来源于stack exchange,提问作者Jakub Kopyś

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:14:12