Pracuję nad bardzo podstawowym systemem koszyków.
Mam tabelę, items
która ma kolumnę price
typu integer
.
Mam problem z wyświetleniem wartości ceny w moich widokach dla cen obejmujących zarówno euro, jak i centy. Czy brakuje mi czegoś oczywistego, jeśli chodzi o obsługę waluty w środowisku Rails?
ruby-on-rails
ruby
currency
Barry Gallagher
źródło
źródło
DECIMAL(19, 4)
jest popularnym wyborem sprawdź to również sprawdź tutaj Formaty waluty światowej, aby zdecydować, ile miejsc po przecinku użyć, nadzieja pomaga.Odpowiedzi:
Prawdopodobnie będziesz chciał użyć
DECIMAL
typu w swojej bazie danych. Podczas migracji wykonaj coś takiego:W Railsach
:decimal
typ jest zwracany jakoBigDecimal
, co doskonale nadaje się do obliczania ceny.Jeśli nalegasz na użycie liczb całkowitych, będziesz musiał ręcznie przekonwertować na
BigDecimal
s wszędzie, co prawdopodobnie stanie się bólem.Jak wskazał mcl, aby wydrukować cenę, użyj:
źródło
Oto dobre, proste podejście, które wykorzystuje
composed_of
(część ActiveRecord, używając wzorca ValueObject) i klejnot MoneyBędziesz potrzebował
Product
integer
kolumna w twoim modelu (i bazie danych):price
Zapisz to w swoim
product.rb
pliku:Co otrzymasz:
product.price = "$12.00"
automatycznie konwertuje do klasy Moneyproduct.price.to_s
wyświetla dziesiętnie sformatowaną liczbę („1234,00”)product.price.format
wyświetla poprawnie sformatowany ciąg dla walutyproduct.price.cents.to_s
źródło
composed_of
tutaj jest więcej szczegółów na ten temat, a także alternatywna implementacja.Powszechną praktyką w zakresie obsługi waluty jest stosowanie typu dziesiętnego. Oto prosty przykład z „Agile Web Development with Rails”
Umożliwi to obsługę cen od -999,999,99 do 999,999,99.
Możesz także chcieć uwzględnić weryfikację w swoich produktach, takich jak
by sprawdzić zdrowie psychiczne.
źródło
Jeśli korzystasz z Postgres (a ponieważ jesteśmy w 2017 roku), możesz
:money
spróbować wypróbować typ kolumny.źródło
Użyj klejnotu z szynami pieniędzy . Ładnie radzi sobie z pieniędzmi i walutami w twoim modelu, a także ma grupę pomocników w sformatowaniu twoich cen.
źródło
Tylko niewielka aktualizacja i spójność wszystkich odpowiedzi dla niektórych początkujących juniorów / początkujących w rozwoju RoR, które z pewnością pojawią się tutaj po kilka wyjaśnień.
Praca z pieniędzmi
Służy
:decimal
do przechowywania pieniędzy w DB, jak sugerował @molf (i co moja firma stosuje jako złoty standard podczas pracy z pieniędzmi).Kilka punktów:
:decimal
będzie używany jakoBigDecimal
rozwiązanie wielu problemów.precision
iscale
należy je dostosować, w zależności od tego, co reprezentujeszJeśli pracujesz z otrzymywaniem i wysyłaniem płatności,
precision: 8
ascale: 2
otrzymasz999,999.99
najwyższą kwotę, co jest w porządku w 90% przypadków.Jeśli chcesz przedstawić wartość nieruchomości lub rzadkiego samochodu, powinieneś użyć wyższej
precision
.Jeśli pracujesz ze współrzędnymi (długość i szerokość geograficzną), na pewno będziesz potrzebować wyższej
scale
.Jak wygenerować migrację
Aby wygenerować migrację z powyższą zawartością, uruchom terminal:
lub
jak wyjaśniono w tym poście na blogu .
Formatowanie walut
POCZUJ dodatkowe biblioteki i pożegnaj się z wbudowanymi pomocnikami. Użyj
number_to_currency
jako @molf i @facundofarias.Grać z
number_to_currency
pomocnika w konsoli Rails, wysłać wezwanie doActiveSupport
„sNumberHelper
klasy w celu uzyskania dostępu do pomocnika.Na przykład:
daje następujący wynik
Sprawdź inne
options
od number_to_currency pomocnika.Gdzie to położyć
Możesz umieścić go w pomocniku aplikacji i używać go w widokach dla dowolnej kwoty.
Możesz też umieścić go w
Item
modelu jako metodę instancji i nazwać go tam, gdzie musisz sformatować cenę (w widokach lub pomocnikach).I przykład, w jaki sposób korzystam z
number_to_currency
wewnątrz kontrolera (zwróć uwagę nanegative_format
opcję, służącą do przedstawienia refundacji)źródło
Korzystając z atrybutów wirtualnych (Link do poprawionej (płatnej) wersji Railscast) , możesz przechowywać swoje price_in_cents w kolumnie liczb całkowitych i dodać wirtualny atrybut price_in_dollars w modelu produktu jako getter i setter.
Źródło: RailsCasts # 016: Wirtualne atrybuty : Wirtualne atrybuty to czysty sposób na dodawanie pól formularzy, które nie są mapowane bezpośrednio do bazy danych. Tutaj pokazuję, jak obsługiwać walidacje, skojarzenia i wiele innych.
źródło
Zdecydowanie liczby całkowite .
I chociaż technicznie istnieje BigDecimal,
1.5
nadal zapewni ci czysty Float w Ruby.źródło
Jeśli ktoś używa Sequel, migracja wyglądałaby mniej więcej tak:
jakoś Sequel ignoruje: precyzję i: skalę
(Sequel Version: sequel (3.39.0, 3.38.0))
źródło
Wszystkie moje podstawowe interfejsy API używały centów do reprezentowania pieniędzy i nie chciałem tego zmieniać. Nie pracowałem też z dużymi pieniędzmi. Po prostu umieściłem to w metodzie pomocniczej:
To konwertuje liczbę całkowitą na ciąg z co najmniej trzema cyframi (w razie potrzeby dodając zera na początku), a następnie wstawia przecinek przed ostatnimi dwiema cyframi, nigdy nie używając
Float
. Stamtąd możesz dodać symbole walut odpowiednie dla danego przypadku użycia.Jest to zdecydowanie szybkie i brudne, ale czasem jest w porządku!
źródło
Używam tego w ten sposób:
Oczywiście symbol waluty, precyzja, format itd. Zależą od każdej waluty.
źródło
Możesz przekazać niektóre opcje do
number_to_currency
(standardowego pomocnika widoku Rails 4):Opublikowane przez Dylan Markow
źródło
Prosty kod dla Ruby & Rails
źródło