有没有办法用两个数据库列来支持新的 Rails 5 属性

Is there a way to back a new Rails 5 attribute with two database columns

我正在考虑将新的 Rails 5 attributes API 用于自定义数据类型,理想情况下将数据存储在两个数据库列中,一个用于数据 value,一个用于一些额外的 [=12] =] 信息。

属性 API 似乎设计为仅使用一个数据库列,我想知道我是否缺少使用两个列的方法。

例子

想象一个 Money 对象,其中一个 decimalinteger 列用于值,一个 string 列用于货币代码。我会传入我的自定义货币对象,将其存储两列,然后读回它会将两列组合成一个货币对象。

我考虑过将价值和货币序列化到单个 Postgres JSON 列中,但我希望能够仅对 SQL SUM 进行快速查询和排序值列,所以这看起来并不理想。

提前感谢您的任何见解。

很遗憾,无法直接回答您的问题,但您的示例让我开始思考。 money-rails gem 允许使用单独的货币列。也许值得深入研究 gem 看看他们在幕后做了什么。

我猜您正在考虑在您的模型中创建一个 ValueObject

ActiveRecord::Aggregations。示例:

class Customer < ActiveRecord::Base
  composed_of :balance, class_name: "Money", mapping: %w(balance amount)
end

class Money
  include Comparable
  attr_reader :amount, :currency
  EXCHANGE_RATES = { "USD_TO_DKK" => 6 }

  def initialize(amount, currency = "USD")
    @amount, @currency = amount, currency
  end

  def exchange_to(other_currency)
    exchanged_amount = (amount * EXCHANGE_RATES["#{currency}_TO_#{other_currency}"]).floor
    Money.new(exchanged_amount, other_currency)
  end

  def ==(other_money)
    amount == other_money.amount && currency == other_money.currency
  end

  def <=>(other_money)
    if currency == other_money.currency
      amount <=> other_money.amount
    else
      amount <=> other_money.exchange_to(currency).amount
    end
  end
end