Я работаю над очень простой системой корзины покупок.
У меня есть таблица, items
которая имеет столбец price
типа integer
.
У меня проблемы с отображением значения цены в моих представлениях для цен, которые включают в себя как евро, так и центы. Я упускаю что-то очевидное в том, что касается обработки валюты в рамках Rails?
ruby-on-rails
ruby
currency
Барри Галлахер
источник
источник
DECIMAL(19, 4)
является популярным выбор проверить это также проверить здесь мировую валюту форматов , чтобы решить , сколько знаков после запятой для использования, надежда помогает.Ответы:
Возможно, вы захотите использовать
DECIMAL
тип в вашей базе данных. В своей миграции сделайте что-то вроде этого:В Rails
:decimal
тип возвращается какBigDecimal
, что отлично подходит для расчета цены.Если вы настаиваете на использовании целых чисел, вам придется вручную конвертировать в и из
BigDecimal
s везде, что, вероятно, станет просто болью.Как указано в mcl, для печати цены используйте:
источник
Вот хороший, простой подход, который использует
composed_of
(часть ActiveRecord, используя шаблон ValueObject) и гем MoneyТебе понадобиться
Product
integer
столбец в вашей модели (и базе данных):price
Запишите это в свой
product.rb
файл:Что вы получите:
product.price = "$12.00"
автоматически конвертируется в класс Moneyproduct.price.to_s
отображает десятичное отформатированное число («1234.00»)product.price.format
отображает правильно отформатированную строку для валютыproduct.price.cents.to_s
источник
composed_of
здесь более подробно об этом, а также об альтернативной реализации.Обычной практикой для обработки валюты является использование десятичного типа. Вот простой пример из "Agile Web Development с Rails"
Это позволит вам обрабатывать цены от -999 999,99 до 999 999,99.
Вы также можете включить проверку в такие элементы, как
в здравом уме - проверь свои ценности.
источник
Если вы используете Postgres (а теперь мы находимся в 2017 году), вы можете
:money
попробовать их тип столбца.источник
Используйте деньги-рельсы драгоценный камень . Он прекрасно обрабатывает деньги и валюты в вашей модели, а также имеет несколько помощников для форматирования ваших цен.
источник
Просто небольшое обновление и сплоченность всех ответов для некоторых начинающих юниоров / новичков в развитии RoR, которые обязательно придут сюда для некоторых объяснений.
Работа с деньгами
Используйте
:decimal
для хранения денег в БД, как предложил @molf (и что моя компания использует как золотой стандарт при работе с деньгами).Несколько баллов:
:decimal
будет использоваться вBigDecimal
качестве решения многих проблем.precision
иscale
должны быть скорректированы, в зависимости от того, что вы представляетеЕсли вы работаете с получением и отправкой платежей,
precision: 8
иscale: 2
вы получаете999,999.99
максимальную сумму, что хорошо в 90% случаев.Если вам нужно представить стоимость имущества или редкого автомобиля, вы должны использовать более высокую
precision
.Если вы работаете с координатами (долгота и широта), вам, безусловно, понадобится больше
scale
.Как создать миграцию
Чтобы сгенерировать миграцию с указанным выше содержимым, запустите в терминале:
или
как объяснено в этом блоге .
Форматирование валюты
ПОЦЕЛУЙТЕ лишние библиотеки до свидания и используйте встроенные помощники. использование
number_to_currency
как предложено @molf и @facundofarias.Для того, чтобы играть с
number_to_currency
помощником в консоли Rails, послать вызов кActiveSupport
-еNumberHelper
класса для доступа помощника.Например:
дает следующий вывод
Проверьте другой
options
из number_to_currency помощника.Где его поставить
Вы можете поместить его в помощник приложения и использовать его внутри представлений на любую сумму.
Или вы можете поместить его в
Item
модель как метод экземпляра и вызывать его там, где вам нужно отформатировать цену (в представлениях или помощниках).И пример того, как я использую
number_to_currency
внутренний контроллер (обратите внимание наnegative_format
опцию, которая используется для представления возвратов)источник
Используя виртуальные атрибуты (ссылка на пересмотренный (платный) Railscast), вы можете сохранить ваши price_in_cents в целочисленном столбце и добавить виртуальный атрибут price_in_dollars в вашу модель продукта в качестве метода получения и установки.
Источник: RailsCasts # 016: Виртуальные атрибуты : Виртуальные атрибуты - это чистый способ добавления полей формы, которые не отображаются непосредственно в базу данных. Здесь я покажу, как обрабатывать проверки, ассоциации и многое другое.
источник
Определенно целые числа .
И хотя технически существующий BigDecimal
1.5
все равно даст вам чистый Float в Ruby.источник
Если кто-то использует Sequel, миграция будет выглядеть примерно так:
как-то сиквел игнорирует: точность и масштаб
(Версия сиквела: продолжение (3.39.0, 3.38.0))
источник
Все мои базовые API использовали центы для представления денег, и я не хотел это менять. Я не работал с большими суммами денег. Так что я просто поместил это во вспомогательный метод:
Это преобразует целое число в строку, содержащую не менее трех цифр (при необходимости добавляя первые нули), затем вставляет десятичную точку перед последними двумя цифрами, никогда не используя a
Float
. Оттуда вы можете добавить любые символы валюты, которые подходят для вашего варианта использования.Это определенно быстро и грязно, но иногда это просто отлично!
источник
Я использую это таким образом:
Конечно, что символ валюты, точность, формат и т. Д. Зависит от каждой валюты.
источник
Вы можете передать некоторые параметры
number_to_currency
(стандартный помощник вида Rails 4):Автор публикации Дилан Марков
источник
Простой код для Ruby & Rails
источник