kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Barry Gallagher
Barry Gallagher
Вопрос

Каков наилучший метод работы с валютой/деньгами?

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

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

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

315 2009-06-19T20:36:18+00:00 13
the  Tin Man
the Tin Man
Редактировал вопрос 1-го февраля 2016 в 5:19
Программирование
ruby
ruby-on-rails
currency
Решение / Ответ
 molf
molf
19-го июня 2009 в 8:48
2009-06-19T20:48:57+00:00
Дополнительно
Источник
Редактировать
#9181127

Вероятно, вы захотите использовать тип DECIMAL в своей базе данных. В миграции сделайте примерно следующее:

# 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

В Rails тип :decimal возвращается как BigDecimal, что отлично подходит для расчета цен.

Если вы настаиваете на использовании целых чисел, вам придется вручную конвертировать в BigDecimal и обратно везде, что, вероятно, станет просто мучением.

Как указал mcl, для печати цены используйте:

number_to_currency(price, :unit => "€")
#=> €1,234.01
 rlandster
rlandster
Редактировал ответ 28-го марта 2017 в 12:35
484
0
Ken Mayer
Ken Mayer
2-го октября 2010 в 12:15
2010-10-02T00:15:14+00:00
Дополнительно
Источник
Редактировать
#9181128

Вот прекрасный, простой подход, использующий composed_of (часть ActiveRecord, использующая паттерн ValueObject) и драгоценный камень Money.

Вам понадобятся

  • Джем Money gem (версия 4.1.0)
  • Модель, например Product.
  • Столбец целое в вашей модели (и базе данных), например :price.

Запишите это в вашем файле product.rb:

class Product > ActiveRecord::Base

  composed_of :price,
              :class_name => 'Money',
              :mapping => %w(price cents),
              :converter => Proc.new { |value| Money.new(value) }
  # ...

Что вы получите:

  • Без каких-либо дополнительных изменений все ваши формы будут показывать доллары и центы, но внутреннее представление будет по-прежнему только центы. Формы будут принимать значения типа "$12,034.95" и конвертировать их для вас. Нет необходимости добавлять дополнительные обработчики или атрибуты в модель или помощники в представление.
  • product.price = "$12.00" автоматически конвертируется в класс Money
  • product.price.to_s выводит десятичное число ("1234.00")
  • product.price.format отображает правильно отформатированную строку для валюты.
  • Если вам нужно отправить центы (в платежный шлюз, который хочет пенни), product.price.cents.to_s.
  • Конвертация валюты бесплатно
Peter Nixey
Peter Nixey
Редактировал ответ 17-го января 2016 в 3:59
113
0
 alex.zherdev
alex.zherdev
19-го июня 2009 в 8:48
2009-06-19T20:48:39+00:00
Дополнительно
Источник
Редактировать
#9181126

Обычно для работы с валютой используется десятичный тип. Вот простой пример из книги "Agile Web Development with Rails"

add_column :products, :price, :decimal, :precision => 8, :scale => 2 

Это позволит вам обрабатывать цены от -999,999.99 до 999,999.99. Возможно, вы также захотите включить в свои элементы валидацию, например

def validate 
  errors.add(:price, "should be at least 0.01") if price.nil? || price < 0.01 
end 

для проверки правильности значений.

25
0
The  Whiz of Oz
The Whiz of Oz
2-го февраля 2017 в 4:35
2017-02-02T16:35:26+00:00
Дополнительно
Источник
Редактировать
#9181136

Если вы используете базы данных Postgres (и так мы'вновь в 2017 году теперь) вы, возможно, захотите, чтобы дать их `:тип столбца деньги попробовать.

add_column :products, :price, :money, default: 0
7
0
 Troggy
Troggy
30-го декабря 2014 в 12:38
2014-12-30T00:38:26+00:00
Дополнительно
Источник
Редактировать
#9181133

Используйте деньги-рельсы камень. Это красиво обрабатывает денег и валюты, в вашей модели, а также имеет кучу помощников для форматирования ценам.

7
0
Thomas Klemm
Thomas Klemm
22-го сентября 2012 в 9:08
2012-09-22T21:08:45+00:00
Дополнительно
Источник
Редактировать
#9181130

Используя виртуальный атрибутами (связь с изменениями(платный) Railscast) вы можете хранить ваши price_in_cents в целочисленном столбце и добавить виртуальный атрибут price_in_dollars в модели продукта, как геттер и сеттер.

# Add a price_in_cents integer column
$ rails g migration add_price_in_cents_to_products price_in_cents:integer

# Use virtual attributes in your Product model
# app/models/product.rb

def price_in_dollars
  price_in_cents.to_d/100 if price_in_cents
end

def price_in_dollars=(dollars)
  self.price_in_cents = dollars.to_d*100 if dollars.present?
end

Источник: RailsCasts #016: виртуальные атрибуты: виртуальные атрибуты-это чистый способ, чтобы добавить поля, которые не отображаются непосредственно в базу данных. Здесь я показываю, как обращаться проверок, организаций, и многое другое.

5
0
 jethroo
jethroo
17-го октября 2012 в 10:35
2012-10-17T10:35:51+00:00
Дополнительно
Источник
Редактировать
#9181131

Если кто-то использует сиквел миграции будет выглядеть так:

add_column :products, :price, "decimal(8,2)"

почему-то продолжение не учитывает :точность и масштаб

(Продолжение версия: сиквел (3.39.0, 3.38.0))

2
0
 facundofarias
facundofarias
17-го февраля 2015 в 5:34
2015-02-17T17:34:18+00:00
Дополнительно
Источник
Редактировать
#9181135

Я использую его на этом пути:

number_to_currency(amount, unit: '€', precision: 2, format: "%u %n")

Разумеется, что символ валюты, точность, формат и так далее, зависит от каждой валюте.

2
0
 moot
moot
6-го сентября 2012 в 9:45
2012-09-06T09:45:11+00:00
Дополнительно
Источник
Редактировать
#9181129

Наверняка целые.

И хотя у bigdecimal технически существует 1.5 все равно даст вам чистый поплавок в Руби.

Rostyslav Dzinko
Rostyslav Dzinko
Редактировал ответ 22-го сентября 2012 в 8:52
2
0
Zlatko Alomerovic
Zlatko Alomerovic
26-го сентября 2018 в 12:05
2018-09-26T00:05:08+00:00
Дополнительно
Источник
Редактировать
#9181138

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

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

Используйте :десятичное хранить деньги в ДБ, как @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

Несколько пунктов:

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

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

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

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

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

Как сгенерировать миграцию

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

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

или

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

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

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

Поцеловать дополнительные библиотеки прощай и использовать встроенные помощники. Number_to_currency Используйте как @molf и @facundofarias предложил.

Играть с number_to_currency помощник в консоли рельсы, отправить вызов ActiveSupport'класса S `NumberHelper для того, чтобы открыть помощник.

Например:

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

дает следующий результат

2500000,61€

Проверьте другие "настройки" number_to_currency помощником.

Куда ее девать

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

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

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

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

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

def refund_information
  amount_formatted = 
    ActionController::Base.helpers.number_to_currency(@refund.amount, negative_format: '(%u%n)')
  {
    # ...
    amount_formatted: amount_formatted,
    # ...
  }
end
Zlatko Alomerovic
Zlatko Alomerovic
Редактировал ответ 26-го сентября 2018 в 2:09
1
0
 blnc
blnc
23-го августа 2014 в 5:31
2014-08-23T05:31:53+00:00
Дополнительно
Источник
Редактировать
#9181132

Вы можете пройти некоторые варианты number_to_currency (стандартная рельсы 4 вспомогательный вид):

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

Как написал Дилан Markow

 Community
Community
Редактировал ответ 23-го мая 2017 в 12:26
1
0
Brent Royal-Gordon
Brent Royal-Gordon
10-го февраля 2015 в 1:42
2015-02-10T01:42:20+00:00
Дополнительно
Источник
Редактировать
#9181134

Мой базовый API были все с использованием центов, чтобы представлять деньги, и я не'т хотим, чтобы это изменить. Я не работаю с большими суммами денег. Так что я просто оставлю это вспомогательный метод:

sprintf("%03d", amount).insert(-3, ".")

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

Это'ы наверняка быстрый и грязный, но иногда это's просто отлично!

Brent Royal-Gordon
Brent Royal-Gordon
Редактировал ответ 10-го февраля 2015 в 1:59
1
0
Dinesh Vaitage
Dinesh Vaitage
30-го марта 2017 в 8:37
2017-03-30T08:37:51+00:00
Дополнительно
Источник
Редактировать
#9181137

Простой код для Ruby & направляющие

<%= number_to_currency(1234567890.50) %>

OUT PUT => $1,234,567,890.50
0
0
Похожие сообщества 6
Чат по Руби
Чат по Руби
2 350 пользователей
Чат-болталка для учеников руби-школы и не только. Сайт школы: https://rubyschool.us Правила: https://telegra.ph/Pravila-chata-Rubi-shkoly-03-13 или тут https://graph.org/Pravila-chata-Rubi-shkoly-03-13
Открыть telegram
RubyRush.ru
RubyRush.ru
2 295 пользователей
Дружелюбный чат для начинающих программистов и учеников rubyrush.ru, обсуждаем программирование, ruby и т. п. Правила чата https://telegra.ph/22-09-05-3 Популярные вопросы (с ответами) https://telegra.ph/22-09-17-4 💎🦜
Открыть telegram
pro.rb (Ruby/Rails / RU)
pro.rb (Ruby/Rails / RU)
1 183 пользователей
Язык программирования Ruby: https://ru.wikipedia.org/wiki/Ruby Вакансии: @rubyjob
Открыть telegram
Ruby — вакансии и аналитика
Ruby — вакансии и аналитика
359 пользователей
Публикуем вакансии и запросы на поиск работы по направлению Ruby. Full-time, part-time, remote и разовые подработки. Обмен инсайдами и аналитикой на рынке труда. Тематическое общение: @ruby_ru См. также: @python_jobs, @nodejs_jobs, @devops_jobs
Открыть telegram
Ruby, Rails, Hanami | dry-rb
Ruby, Rails, Hanami | dry-rb
345 пользователей
Открыть telegram
Ruby Talks
Ruby Talks
255 пользователей
Национальная Флеймотека
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 5 дней назад
2
Денис Васьков
Зарегистрирован 1 неделю назад
3
Dima Patrushev
Зарегистрирован 1 неделю назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
ES
ID
JA
KO
RO
RU
ZH
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией