348 votes

Ruby on Rails: meilleure méthode de gestion de la monnaie / argent

Je suis nouveau sur Ruby on Rails et je travaille sur un système de panier très basique. J’ai une table qui possède une colonne de de type `` . Je ne parviens pas afficher la valeur de prix dans mon point de vue des prix qui incluent Euros et en cents. Ai-je raté quelque chose d’évident comme monnaie dans le cadre de Rails de manutention est concerné ?

523voto

molf Points 34978

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

# precision is the total amount of digits
# scale is the number of digits right of the decimal point
add_column :items, :price, :decimal, :precision => 8, :scale => 2

Dans les Rails, l' :decimal type est retourné en tant que BigDecimal, ce qui est excellent pour le calcul du prix.

Si vous insistez sur l'utilisation de nombres entiers, vous devrez manuellement convertir BigDecimals partout, ce qui va probablement devenir une douleur.

Comme l'a souligné la mcl, pour imprimer le prix, utilisez:

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

122voto

Ken Mayer Points 793

Voici une amende, une approche simple qui exploite composed_of (une partie de ActiveRecord, à l'aide de la ValueObject modèle) et de l'Argent gem

Vous aurez besoin

  • L' Argent gem (version 4.1.0)
  • Un exemple, c'est - Product
  • Un integer colonne dans votre modèle et base de données), par exemple :price

Écrire ceci dans votre product.rb le fichier:

class Product > ActiveRecord::Base

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

Ce que vous obtiendrez:

  • Sans changements supplémentaires, tous vos formulaires d'afficher des dollars et des cents, mais la représentation interne est toujours cents. Les formulaires d'accepter des valeurs comme "$12,034.95" et de le convertir pour vous. Il n'y a pas besoin d'ajouter des gestionnaires ou des attributs à votre modèle, ou des aides dans votre point de vue.
  • product.price = "$12.00" convertit automatiquement de l'Argent de la classe
  • product.price.to_s affiche un nombre décimal nombre formaté ("1234.00")
  • product.price.format affiche une chaîne formatée correctement pour la monnaie
  • Si vous avez besoin d'envoyer cents (à une passerelle de paiement qui veut centimes), en product.price.cents.to_s
  • Conversion de devises gratuit

28voto

neutrino Points 11643

Une pratique courante pour la manipulation des devises consiste à utiliser le type decimal. Voici un exemple simple de « Agile Web Development avec Rails »

Cela vous permettra de gérer les prix entre-999,999.99 et 999,999.99
Vous pouvez également inclure une validation dans vos objets comme

santé mentale-vérifier vos valeurs.

5voto

Thomas Klemm Points 4335

En utilisant les Attributs Virtuels (Lien vers révisée(payé) Railscast) vous pouvez stocker vos price_in_cents dans une colonne de type integer et ajouter un champ virtuel price_in_dollars dans votre modèle de produit comme un getter et setter.

# 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

Source: RailsCasts #016: Virtuel Attributs: les attributs Virtuels sont un moyen propre pour ajouter des champs de formulaire qui ne correspondent pas directement à la base de données. Ici, je montre comment gérer les validations, les associations, et plus encore.

3voto

moot Points 1

Sans aucun doute des entiers.

Et même si BigDecimal existe techniquement `` encore vous donnera un flotteur pur en Ruby.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X