Как мне преобразовать десятичное в строковое значение для долларов и центов в рубине? - PullRequest
5 голосов
/ 14 апреля 2009

Я храню стоимость в моей заявке. Стоимость не отформатирована в базе данных. Например: 00,00 сохраняет как 0, 1,00 сохраняет как 1, а 40.50 сохраняет как 40,5

Мне нужно прочитать эти значения из базы данных и преобразовать их в строки за доллары и центы. Например: 0 -> cost_dollars = "00" & cost_cents = "00", 1 -> cost_dollars = "01" & cost_cents = "00", 40.5 -> cost_dollars = "40" & cost_cents = "50" .

Есть ли простой способ сделать это в ruby ​​на рельсах? Или у кого-то есть код, который делает это?

Спасибо!

Ответы [ 5 ]

18 голосов
/ 14 апреля 2009

Вы можете сделать это с помощью небольшого кусочка кода Ruby:

fmt = "%05.2f" % cost
cost_dollars, cost_cents = fmt.split '.'
8 голосов
/ 14 апреля 2009

Если вы пытаетесь отформатировать долларовые значения в представлении, вы должны посмотреть на number_to_currency в ActionView :: Helpers :: NumberHelper.

>> bd = BigDecimal.new "5.75"   
>> include ActionView::Helpers
>> number_to_currency(bd)
=> "$5.75"

Что касается разбиения стоимости на отдельные доллары и центы, мой первый вопрос будет: "Почему?" Если у вас есть веская причина, и вы имеете дело с десятичными знаками в своей базе данных, вы можете сделать следующее.

>> bd = BigDecimal.new "5.75"
>> "dollars:#{bd.truncate} cents:#{bd.modulo(1) * BigDecimal.new('100')}"
=> "dollars:5.0 cents:75.0"
7 голосов
/ 14 апреля 2009

number_to_currency приятно, но может дорого обойтись; Возможно, вы захотите сделать свой собственный бросок, если вам нужно часто это называть.

Вы должны знать, что использование плавающей запятой для хранения валюты может быть проблематичным ( и см. ), если вы выполняете много расчетов на основе этих значений. Одним из решений является использование целых чисел для валюты и подсчета центов. Похоже, что это подход, используемый плагин денег . Другое решение заключается в использовании типа decimal в вашей миграции, который должен работать «из коробки» для современных версий Rails (> 1.2):

add_column :items, :price, :decimal, :precision => 10, :scale => 2

(:scale - это число знаков после запятой, :precision - общее количество цифр.) Это даст вам BigDecimal объектов в Rails, с которыми немного сложнее работать , но не так уж и плохо.

И целочисленный, и десятичный подходы немного медленнее, чем с плавающей запятой. В некоторых местах я использую плавающие числа для валюты, потому что я знаю, что мне не нужно делать вычисления для значений в Rails, только хранить и отображать их. Но если вам нужны точные расчеты валюты, не используйте поплавки.

5 голосов
/ 14 апреля 2009

Вместо хранения в виде десятичной дроби, храните как целое число центов. Таким образом, 1 доллар хранится в базе данных как 100.

В качестве альтернативы, если вы не возражаете против небольшого снижения производительности, проверьте «.» в значении базы данных. Если он существует, разделите его на «.» И проанализируйте части как целые числа.

2 голосов
/ 14 апреля 2009

sprintf ваш друг здесь:

cost_dollars = sprintf('%02.f', cost)
cost_cents = sprintf('%.2f', cost)
...