簡體   English   中英

Money-Rails 丟棄小數點后的價格金額

[英]Money-Rails is discarding price amount after decimal point

我正在構建和 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!

您的價格(美分)! 沒關系!

以美分處理金錢是一種常見的模式。 當涉及到稅收或貨幣兌換的舍入錯誤時,它還可以挽救您的生命。 就像在他們的文檔中提到的那樣,您應該使用幫助程序以人類可讀的形式輸出價格:

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

保存/創建模型:如果你得到一個浮點數,你可以在_save之前將浮點數更改為美分

before_save :convert_transaction_price
def convert_transaction_price
   self.transaction_price = (self.transaction_price * 100).to_i
end

我有同樣的問題。
(編輯新的和正確的答案):

我所要做的就是使用 money-rails gem 中提供的屬性。 在我的例子中,我有一個amount_cents屬性,我必須在表單中使用提供的:amount屬性。

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

注意:我將:amount_cents的值轉換為:amount_cents中的浮點字符串,如下edit.html.erb

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

另請注意,我已將貨幣軌配置為使用使用“,”作為分隔符的.gsbu(/\\./, ',') ,這就是我必須使用.gsbu(/\\./, ',')

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

    private

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

——

(舊答案):
我得出的結論是,最好直接將 Frontend 中的輸入值更改為 cents。 然后將美分發送到后端。

這是一個很好的刺激控制器,它正是這樣做的:https ://gist.github.com/psergi/72f99b792a967525ffe2e319cf746101
(您可能需要根據自己的喜好更新該要點,並且它希望您在 Rails 項目中使用 Stimulus)

(我把舊答案留在這里,因為我認為從前端發送 _cents 到后端是一個很好的做法,但目前沒有必要[對我來說]。如果你想支持一種以上的貨幣,您可能想這樣做並使用 .js 框架來處理輸入轉換 -> s.th. 像http://autonumeric.org/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM