Руби и деньги, в приложении rails, как хранить денежные значения в БД? - PullRequest
10 голосов
/ 22 февраля 2011

Я хочу убедиться, что у меня нет проблем с округлением, когда дело доходит до хранения цен на продукты в приложении rails.

Какой тип данных mysql я должен использовать и на что он указывает в рельсах?

Я хочу десятичность с 10 точками для точности.

Ответы [ 5 ]

13 голосов
/ 22 февраля 2011

Я предпочитаю хранить валюту в базе данных как целое число наименьшего номинала (пенсов, центов и т. Д.) И выполнять вычисления на основе этого.

add_column :product, :price, :integer

Конечно, вы захотите, чтобы любой ввод и отображение формы были в той форме, которую ожидают люди, поэтому мы добавим в модель несколько вспомогательных методов, чтобы помочь с этим.

class Product < ActiveRecord::Base
  def price_dollars
    self.price / 100
  end

  def price_dollars=(val)
    self.price = val * 100
  end
end

В консоли мы получаем:

> prod = Product.new
=> [snip]

> prod.price_dollars = 12.93
=> 12.93
> prod.price
=> 1293
> prod.price_dollars
=> 12.93

> prod.price = 1691
=> 1691
> prod.price_dollars
=> 16.91

Я уверен, что, вероятно, есть плагин, который прекрасно справится с этим.

11 голосов
/ 22 февраля 2011

Звучит, что вы хотите :decimal тип столбца.Вы можете контролировать общее количество цифр и количество знаков после запятой с помощью параметров :precision и :scale:

add_column :mytable, :mycolumn, :decimal, :precision => 30, :scale => 10

Немного больше о типах данных в этой документации (Понятия не имею, что такое функция column - возможно, внутренняя!).

Надеюсь, это поможет!

2 голосов
/ 12 декабря 2014

Добавление к превосходному ответу Дугласа выше:

Чтобы это работало, по крайней мере в Ruby 2.1.4, вам нужно преобразовать поле: price в число с плавающей запятой или десятичное при делении на 100.

Деление целого числа на другое целое число

1293/100

не вернет то, что вы могли ожидать. Вместо получения 12,93 Ruby возвращает 12 целое число.

2.1.4 :002 > 1293 / 100
=> 12
2.1.4 :003 > 1293.to_f / 100
=> 12.93

Пример кода модели продукта

class Product < ActiveRecord::Base
  def price_dollars
    self.price.to_f / 100
  end

  def price_dollars=(val)
    self.price = val * 100
  end
end
1 голос
/ 22 февраля 2011

Я думаю, что всегда легче хранить ваш наименьший общий знаменатель как целое число в базе данных (вот вопрос, в котором мы использовали центы: Обработка ввода международной валюты в Ruby on Rails , но вы можете хранить цены в 1/10 000 центов, если хотите), и делайте правильную математику, когда вынимаете число из БД.

0 голосов
/ 22 февраля 2011

Используйте "float"

add_column :customer, :amount, :float
...