Каков наилучший метод обращения с валютой / деньгами? - PullRequest
314 голосов
/ 20 июня 2009

Я работаю над очень простой системой корзины покупок.

У меня есть таблица items, в которой есть столбец price типа integer.

У меня проблемы с отображением значения цены в моих представлениях для цен, которые включают как евро, так и центы. Я упускаю что-то очевидное в том, что касается обработки валюты в Rails-фреймворке?

Ответы [ 13 ]

1 голос
/ 23 августа 2014

Некоторые параметры можно передать number_to_currency (стандартный помощник вида Rails 4):

number_to_currency(12.0, :precision => 2)
# => "$12.00"

Автор: Дилан Марков

0 голосов
/ 26 сентября 2018

Просто небольшое обновление и сплоченность всех ответов для некоторых начинающих юниоров / новичков в развитии RoR, которые обязательно придут сюда для некоторых объяснений.

Работа с деньгами

Используйте :decimal для хранения денег в БД, как предложил @molf (и что моя компания использует как золотой стандарт при работе с деньгами).

# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, precision: 8, scale: 2

Несколько баллов:

  • :decimal будет использоваться как BigDecimal, что решает множество проблем.

  • precision и scale должны быть скорректированы в зависимости от того, что вы представляете

    • Если вы работаете с получением и отправкой платежей, precision: 8 и scale: 2 дают вам 999,999.99 в качестве максимальной суммы, что хорошо в 90% случаев.

    • Если вам нужно представить стоимость имущества или редкого автомобиля, вы должны использовать более высокое значение precision.

    • Если вы работаете с координатами (долгота и широта), вам, безусловно, потребуется более высокое значение scale.

Как создать миграцию

Чтобы сгенерировать миграцию с указанным выше содержимым, запустите в терминале:

bin/rails g migration AddPriceToItems price:decimal{8-2}

или

bin/rails g migration AddPriceToItems 'price:decimal{5,2}'

как объяснено в этом блоге пост.

Форматирование валюты

KISS прощайте лишние библиотеки и используйте встроенные помощники. Используйте number_to_currency в качестве @molf и @facundofarias.

Чтобы поиграть с помощником number_to_currency в консоли Rails, отправьте вызов классу ActiveSupport NumberHelper, чтобы получить доступ к помощнику.

Например:

ActiveSupport::NumberHelper.number_to_currency(2_500_000.61, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")

дает следующий вывод

2500000,61€

Проверьте остальные options из number_to_currency помощник.

Где его поставить

Вы можете поместить его в помощник приложения и использовать его в любом виде.

module ApplicationHelper    
  def format_currency(amount)
    number_to_currency(amount, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
  end
end

Или вы можете поместить его в модель Item как метод экземпляра и вызывать его там, где вам нужно отформатировать цену (в представлениях или помощниках).

class Item < ActiveRecord::Base
  def format_price
    number_to_currency(price, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
  end
end

И, например, как я использую number_to_currency внутри контроллера (обратите внимание на параметр negative_format, используемый для представления возвратов)

def refund_information
  amount_formatted = 
    ActionController::Base.helpers.number_to_currency(@refund.amount, negative_format: '(%u%n)')
  {
    # ...
    amount_formatted: amount_formatted,
    # ...
  }
end
0 голосов
/ 30 марта 2017

Простой код для Ruby & Rails

<%= number_to_currency(1234567890.50) %>

OUT PUT => $1,234,567,890.50
...