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é ?
Réponses
Trop de publicités?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 BigDecimal
s 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
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
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.
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.