Просто небольшое обновление и сплоченность всех ответов для некоторых начинающих юниоров / новичков в развитии 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