Why do I see different behavior here?
While doing the cast in IEX I see the expected result:
iex [17:06 :: 22] > %{"amount" => "1.5", "currency" => "EUR"} |> Money.Ecto.Composite.Type.cast()
{:ok, Money.new(:EUR, "1.5")}
the application is somehow respecting the locale setting (which is “de” in the case and “.” is not a comma delimiter but “,” is):
Map.get(params, "balance") #=> "{\"currency\":\"EUR\",\"amount\":\"1.00\"}"
|> Jason.decode!() #=> %{"amount" => "1.00", "currency" => "EUR"}
|> Money.Ecto.Composite.Type.cast() #=> {:ok, Money.new(:EUR, "100")}
Thus getting back a Money value multiplied by 100
One might set the default locale in custom Cldr
module as
defmodule MyApp.Cldr do
use Cldr, locales: ["en", "fr", "de"], default_locale: "en"
end
or explicitly pass the locale in a call to cast/2
(no idea why it’s not documented, a PR documenting it would be appreciated, I believe.)
iex|🌢|1 ▶ %{"amount" => "1.00", "currency" => "EUR"}
|> Money.Ecto.Composite.Type.cast(locale: :de)
{:ok, Money.new(:EUR, "100")}
iex|🌢|2 ▶ %{"amount" => "1.00", "currency" => "EUR"}
|> Money.Ecto.Composite.Type.cast(locale: :en)
{:ok, Money.new(:EUR, "1.00")}
1 Like
Yeah, the issue here is that cast
expects human format (formatted to the locale rules of the user), not machine format. If you need the later you need to make sure the decoding happens using the correct locale.
@mudasobwa @LostKobrakai
Thanks a lot.
Checked the documentation for cast
more carefully
I did not know that cast has a locale
option
kip
August 2, 2024, 11:54pm
5
Typically I don’t document behaviour implementations, but I agree that in this case its important to understand the behaviour (no pun intended) of Money.Ecto.Composite.Type.cast/2
.
I’ve published documentation for Money.Ecto.Composite.Type.cast/2 and would welcome any PRs that improve it.
3 Likes