使用 money-rails gem,将实例货币切换为欧元中断更新
Using money-rails gem, switching instance currency to Euro breaks updates
我有一个名为 Widget
的模型,它有一个名为 advance
.
的货币化属性
Widget
的每个实例可能有一个 advance
属性,用于存储唯一的货币和金额。
尽管所有设置都基于 gem 文档,并且能够在默认货币 USD
和切换到其他货币之间切换,例如 JPY
、CSD
、CNY
、切换到 EUR
会引发错误并阻止更新 advance_currency
和 advance_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>
我有一个名为 Widget
的模型,它有一个名为 advance
.
Widget
的每个实例可能有一个 advance
属性,用于存储唯一的货币和金额。
尽管所有设置都基于 gem 文档,并且能够在默认货币 USD
和切换到其他货币之间切换,例如 JPY
、CSD
、CNY
、切换到 EUR
会引发错误并阻止更新 advance_currency
和 advance_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>