ruby-on-rails ruby - Quelle est la meilleure méthode de gestion de la monnaie / argent?




money currency (11)

Voici une approche fine et simple qui exploite compose_of (une partie d'ActiveRecord, en utilisant le pattern ValueObject) et la gemme Money

Tu auras besoin

  • The Money gem (version 4.1.0)
  • Un modèle, par exemple Product
  • Une colonne integer dans votre modèle (et base de données), par exemple :price

Ecrivez ceci dans votre fichier product.rb :

class Product > ActiveRecord::Base

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

Ce que vous aurez:

  • Sans aucun changement supplémentaire, tous vos formulaires afficheront des dollars et des cents, mais la représentation interne ne représente encore que quelques cents. Les formulaires accepteront des valeurs comme "$ 12,034.95" et le convertiront pour vous. Il n'est pas nécessaire d'ajouter des gestionnaires ou des attributs supplémentaires à votre modèle, ou des aides à votre vue.
  • product.price = "$12.00" convertit automatiquement à la classe Money
  • product.price.to_s affiche un nombre au format décimal ("1234.00")
  • product.price.format affiche une chaîne correctement formatée pour la devise
  • Si vous avez besoin d'envoyer des cents (à une passerelle de paiement qui veut des centimes), product.price.cents.to_s
  • Conversion de devises gratuite

Je travaille sur un système de panier d'achat très basique.

J'ai un items table qui a un price de colonne de type integer .

J'ai des difficultés à afficher la valeur du prix dans mes vues pour les prix qui comprennent à la fois les euros et les cents. Suis-je en train de manquer quelque chose d'évident en ce qui concerne la gestion de la monnaie dans le cadre de Rails?


Vous voudrez probablement utiliser un type DECIMAL dans votre base de données. Dans votre migration, faites quelque chose comme ceci:

# 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

Dans Rails, le type :decimal est renvoyé en BigDecimal , ce qui est idéal pour le calcul du prix.

Si vous insistez sur l'utilisation de nombres entiers, vous devrez convertir manuellement vers et depuis BigDecimal partout, ce qui deviendra probablement juste une douleur.

Comme indiqué par mcl, pour imprimer le prix, utilisez:

number_to_currency(price, :unit => "€")
#=> €1,234.01

Si vous utilisez Postgres (et que nous sommes en 2017), vous pouvez essayer le type de colonne :money .

add_column :products, :price, :money, default: 0

Définitivement des integers .

Et même si BigDecimal existe techniquement, 1.5 vous donnera toujours un Float pur en Ruby.


Je l'utilise de cette façon:

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

Bien sûr que le symbole monétaire, la précision, le format et ainsi de suite dépend de chaque devise.


La pratique courante pour manipuler la devise est d'utiliser le type décimal. Voici un exemple simple de "Agile Web Development with Rails"

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

Cela vous permettra de gérer les prix de -999 999,99 à 999 999,99
Vous pouvez également inclure une validation dans vos articles comme

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

à la santé-vérifier vos valeurs.


Si quelqu'un utilise Sequel, la migration ressemblerait à ceci:

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

d'une certaine manière Sequel ignore: précision et: échelle

(Version de suite: suite (3.39.0, 3.38.0))


Code simple pour Ruby & Rails

<%= number_to_currency(1234567890.50) %>

OUT PUT => $1,234,567,890.50

Utilisez la rails-money . Il gère bien l'argent et les devises dans votre modèle et a également un tas d'aides pour formater vos prix.


Vous pouvez passer certaines options à number_to_currency (une aide de vue Rails 4 standard):

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

Publié par Dylan Markow


Créez votre propre classe. Cela semble étrange, mais un type .Net est inadéquat pour couvrir différentes devises.





ruby-on-rails ruby currency