0

我正在构建 Rails 5 API,我试图在其中发送金额并将其存储在 PostgresQL 数据库中。我发送的金额为 2.4,但我在数据库中看到仅存储了 2 个。我做错了什么?

我的迁移:

class CreateTransactions < ActiveRecord::Migration[5.1]
  def change
  create_table :transactions do |t|
   t.monetize :transaction_price, amount: { null: true, default: nil }
   t.timestamps
  end
 end
end

我的模型是:

class Transaction < ApplicationRecord
  monetize :transaction_price_cents
end

我的控制器:

class TransactionsController < ApiController
      def create
        transaction = Transaction.new(transaction_param)
        if transaction.save
          render json: { status: 'SUCCESS', data:transaction }, status: :ok
        end
      end

      private
      def transaction_param
        params.require(:transaction).permit(:transaction_price_cents)
      end
end

我用邮递员发送这个json:

{
    "transaction_price_cents": 345.23
}

我得到的回应是:

{
    "status": "SUCCESS",
    "data": {
        "id": 1,
        "transaction_price_cents": 345,
        "transaction_price_currency": "USD",
    }
}

我要么想要 345.23 要么 34523 但它只给我 345!

4

2 回答 2

1

以美分为单位的价格!没关系!

以美分处理货币是一种常见的模式。当涉及税收或货币兑换的四舍五入错误时,它还将挽救您的生命。就像在他们的文档中提到的那样,您应该使用帮助程序以人类可读的形式输出价格:

humanized_money @money_object                       # => 6.50
humanized_money_with_symbol @money_object           # => $6.50
money_without_cents_and_with_symbol @money_object   # => $6

如果您通过 API 访问数据,您可以在您的 api 中添加 human_readable 字段

def transaction_price_human_readable
  return humanized_money_with_symbol(@money_object) # or self or...
end

保存/创建模型:如果你得到一个浮点数,你可以将浮点数更改为美分 before_save

before_save :convert_transaction_price
def convert_transaction_price
   self.transaction_price = (self.transaction_price * 100).to_i
end
于 2018-03-07T21:13:13.833 回答
0

我有同样的问题。
(编辑新的和正确的答案):

我所要做的就是使用 money-rails gem 中提供的属性。就我而言,我有一个amount_cents属性,我必须:amount在表单中使用提供的属性。

<%= f.label :amount %>
<%= f.text_field :amount %>

注意:我将值转换为:amount_cents浮点字符串,edit.html.erb如下所示:

<%= f.label :amount %>
<%= f.text_field :amount, value: number_with_precision(f.object.amount_cents / 100, precision: 2).gsub(/\./, ',') %>

另请注意,我已将money-rails配置为使用使用“,”作为分隔符的欧元,这就是我必须使用的原因.gsbu(/\./, ',')

这是重要的部分,我必须在控制器中更新我的strong_parameters以允许:amount,而不是:amount_cents

    private

        def invoice_params
            params.require(:invoice).permit(…, :amount, …)
        end     

--

(旧答案):
我得出的结论是,最好直接在前端将输入值更改为美分。然后将美分发送到后端。

这是一个很好的 Stimulus 控制器,它可以做到这一点:https
://gist.github.com/psergi/72f99b792a967525ffe2e319cf746101 (您可能需要根据自己的喜好更新该要点,并且它还希望您在 rails 项目中使用 Stimulus)

(我把旧答案留在这里,因为我认为将_cents从前端发送到后端是一个好习惯,但目前[对我来说]没有必要。如果你想支持一种以上的货币,您可能想这样做并使用 .js 框架来处理输入转换-> s.th. 像http://autonumeric.org/

于 2021-01-14T13:16:05.487 回答