Estoy trabajando en un sistema de carrito de compras muy básico.
Tengo una tabla items
que tiene una columna price
de tipo integer
.
Tengo problemas para mostrar el valor del precio en mis vistas para precios que incluyen euros y centavos. ¿Me estoy perdiendo algo obvio en lo que respecta al manejo de divisas en el marco de Rails?
ruby-on-rails
ruby
currency
Barry Gallagher
fuente
fuente
DECIMAL(19, 4)
es una opción popular, marque esto y marque aquí Formatos de moneda mundial para decidir cuántos decimales usar, la esperanza ayuda.Respuestas:
Probablemente quieras usar un
DECIMAL
tipo en tu base de datos. En su migración, haga algo como esto:En Rails, el
:decimal
tipo se devuelve comoBigDecimal
, lo cual es excelente para el cálculo del precio.Si insiste en usar números enteros, tendrá que convertir manualmente hacia y desde
BigDecimal
s en todas partes, lo que probablemente se convierta en una molestia.Como señaló mcl, para imprimir el precio, use:
fuente
Aquí hay un enfoque simple y fino que aprovecha
composed_of
(parte de ActiveRecord, usando el patrón ValueObject) y la gema MoneyNecesitarás
Product
integer
columna en su modelo (y base de datos), por ejemplo:price
Escribe esto en tu
product.rb
archivo:Lo que obtendrás:
product.price = "$12.00"
se convierte automáticamente a la clase Moneyproduct.price.to_s
muestra un número con formato decimal ("1234.00")product.price.format
muestra una cadena con el formato correcto para la monedaproduct.price.cents.to_s
fuente
composed_of
aquí, hay más detalles al respecto, así como una implementación alternativa.La práctica común para manejar la moneda es usar el tipo decimal. Aquí hay un ejemplo simple de "Desarrollo web ágil con rieles"
Esto le permitirá manejar precios de -999,999.99 a 999,999.99
También puede incluir una validación en sus artículos como
para comprobar la cordura de sus valores.
fuente
Si está utilizando Postgres (y desde que estamos en 2017 ahora) es posible que desee
:money
probar su tipo de columna.fuente
Usa gemas de rieles de dinero . Maneja muy bien el dinero y las monedas en su modelo y también tiene un montón de ayudantes para formatear sus precios.
fuente
Solo una pequeña actualización y una cohesión de todas las respuestas para algunos aspirantes a junior / principiantes en el desarrollo de RoR que seguramente vendrán aquí para algunas explicaciones.
Trabajando con dinero
Utilice
:decimal
para almacenar dinero en el PP, como @molf sugirió (y lo que mis usos de la empresa como un estándar de oro cuando se trabaja con dinero).Pocos puntos:
:decimal
se usará paraBigDecimal
resolver muchos problemas.precision
yscale
debe ajustarse, según lo que esté representandoSi trabaja con recibir y enviar pagos,
precision: 8
yscale: 2
le da999,999.99
la cantidad más alta, que está bien en el 90% de los casos.Si necesita representar el valor de una propiedad o un automóvil raro, debe usar uno más alto
precision
.Si trabaja con coordenadas (longitud y latitud), seguramente necesitará una más alta
scale
.Cómo generar una migración
Para generar la migración con el contenido anterior, ejecute en la terminal:
o
como se explica en esta publicación de blog .
Formato de moneda
BESE las bibliotecas adicionales adiós y use ayudantes incorporados. Use
number_to_currency
como @molf y @facundofarias sugirieron.Para jugar con el
number_to_currency
ayudante en la consola de Rails, envíe una llamada a la claseActiveSupport
'sNumberHelper
para acceder al ayudante.Por ejemplo:
da el siguiente resultado
Verifique el otro número de ayudante
options
de número a monedaDonde ponerlo
Puede ponerlo en una aplicación auxiliar y usarlo dentro de las vistas por cualquier cantidad.
O puede ponerlo en el
Item
modelo como un método de instancia y llamarlo donde necesite formatear el precio (en vistas o ayudantes).Y, un ejemplo de cómo uso el
number_to_currency
controlador interno (observe lanegative_format
opción, utilizada para representar reembolsos)fuente
Usando Atributos Virtuales (Enlace a Railscast revisado (pagado)) puede almacenar su price_in_cents en una columna de enteros y agregar un atributo virtual price_in_dollars en su modelo de producto como getter y setter.
Fuente: RailsCasts # 016: Atributos virtuales : los atributos virtuales son una forma limpia de agregar campos de formulario que no se asignan directamente a la base de datos. Aquí muestro cómo manejar validaciones, asociaciones y más.
fuente
Definitivamente enteros .
Y a pesar de que BigDecimal técnicamente existe
1.5
, todavía te dará un Float puro en Ruby.fuente
Si alguien usa Sequel, la migración se vería así:
de alguna manera Sequel ignora: precisión y escala
(Versión de la secuela: secuela (3.39.0, 3.38.0))
fuente
Mis API subyacentes estaban usando centavos para representar dinero, y no quería cambiar eso. Tampoco estaba trabajando con grandes cantidades de dinero. Así que acabo de poner esto en un método auxiliar:
Eso convierte el número entero en una cadena con al menos tres dígitos (agregando ceros a la izquierda si es necesario), luego inserta un punto decimal antes de los dos últimos dígitos, sin usar nunca un
Float
. Desde allí, puede agregar los símbolos de moneda que sean apropiados para su caso de uso.Es sin duda rápido y sucio, pero a veces eso está bien!
fuente
Lo estoy usando de esta manera:
Por supuesto, el símbolo de la moneda, la precisión, el formato, etc. dependen de cada moneda.
fuente
Puede pasar algunas opciones a
number_to_currency
(un asistente de vista estándar de Rails 4):Publicado por Dylan Markow
fuente
Código simple para Ruby & Rails
fuente