使用 money-rails gem,将实例货币切换为欧元中断更新

Using money-rails gem, switching instance currency to Euro breaks updates

我有一个名为 Widget 的模型,它有一个名为 advance.

的货币化属性

Widget 的每个实例可能有一个 advance 属性,用于存储唯一的货币和金额。

尽管所有设置都基于 gem 文档,并且能够在默认货币 USD 和切换到其他货币之间切换,例如 JPYCSDCNY、切换到 EUR 会引发错误并阻止更新 advance_currencyadvance_cents 值。

Gem 文件

ruby "3.1.2"
gem "rails", "7.0.2.3"
gem "money-rails", "1.15.0"

初始化文件

Money.locale_backend = :currency

MoneyRails.configure do |config|
  config.default_currency = :usd
  config.include_validations = true
  config.rounding_mode = BigDecimal::ROUND_HALF_UP
end

迁移设置

create_table :widgets, force: :cascade do |t|

  ...

  t.monetize :advance, amount: { limit: 8 }
end

架构

create_table "widgets", force: :cascade do |t|

    ...

    t.bigint "advance_cents", default: 0, null: false
    t.string "advance_currency", default: "USD", null: false

    ...

end

模型设置

class Widget < ApplicationRecord

  ...

  monetize :advance_cents, with_model_currency: :advance_currency

  ...

end

编辑表单视图片段

  <div class="form-floating">
    <%= select_tag("advance_currency", options_for_select(CurrencyTypes.options_for_select, @instance.advance_currency), prompt: "Select a currency", class: "form-select") %>
    <label for="advance_currency" class="form-label">Advance Currency</label>
  </div>
  <div class="form-floating">
    <input type="number" step="any" class="form-control" id="advance" name="advance" value="<%= number_to_currency(@instance.advance, unit: "", separator: ".") %>">
    <label for="advance" class="form-label">Advance Amount</label>
  </div>

控制器更新操作

def update
  instance = controller_class.find(params[:id])
  instance.update(update_params)

  ...

end

private

def update_params
  params.permit(

    ...

    :advance,
    :advance_currency,

    ...

  )
end

消息切换为日元(有效)

参数检查

#<ActionController::Parameters {

  ...

  "advance_currency"=>"JPY",
  "advance"=>"987.65", 
} permitted: false>

调试更新

> instance.update(update_params)
> instance.save

true

调试错误

> instance.errors

#<ActiveModel::Errors []>

切换到欧元的错误消息(不起作用)

参数检查

#<ActionController::Parameters {

  ...

  "advance_currency"=>"EUR",
  "advance"=>"123.45", 
} permitted: false>

调试更新

> instance.update(update_params)
> instance.save

false

调试错误

> instance.errors

#<ActiveModel::Errors [#<ActiveModel::Error attribute=advance, type=invalid_currency, options={:thousands=>".", :decimal=>",", :currency=>"123.45", :attribute=>"Advance"}>]>

没有任何意义的是,当切换到欧元作为货币时,预付款似乎输入到 currency 值而不是 EUR

我不知道为什么一种货币会抛出货币-rails gem 操作而其他货币正常工作。

似乎是使用 number 类型输入的问题。

您只能使用 123.456,78 格式提交欧元值,而不是 123,456.78 格式的其他货币。

由于number输入类型中不允许使用逗号,必须切换为text

类型

不工作

<div class="form-floating">
  <input type="number" class="form-control" id="advance" name="advance" value="<%= @instance.advance %>">
  <label for="advance" class="form-label">Advance Amount</label>
</div>

工作

<div class="form-floating">
  <input type="text" class="form-control" id="advance" name="advance" value="<%= @instance.advance %>">
  <label for="advance" class="form-label">Advance Amount</label>
</div>