A User resource has attribute :mobile_phone, :string, allow_nil?: false. The user can edit his/her phone number. The problem is that in Germany human users use different format to enter their phone number. But I want to save it in e164 format.
Hello, I’m assuming that you want to store it in the database.
If you want to manipulate the data before it is saved and after it is fetched from DB, I would use the Ecto.Type behaviour to create your own custom field “Phone”. Here is the documentation.
You can take a look at this library ecto_phone_number | Hex to check if it does what you want. You can also read the definition of their custom Ecto.Typehere as reference to implement yours.
defmodule YourApp.AshPhoneNumber do
@moduledoc """
PhoneNumber Type to store the number in a e164 format.
"""
use Ash.Type
@impl Ash.Type
def storage_type(_), do: :string
@impl Ash.Type
def cast_input(nil, _), do: {:ok, nil}
def cast_input(value, _) do
ecto_type_cast = Ecto.Type.cast(:string, value)
{:ok, raw_phone_number} = ecto_type_cast
case ExPhoneNumber.parse(raw_phone_number, "DE") do
{:ok, phone_number} ->
case ExPhoneNumber.is_possible_number?(phone_number) do
true -> {:ok, ExPhoneNumber.format(phone_number, :e164)}
_ -> ecto_type_cast
end
_ ->
ecto_type_cast
end
end
@impl Ash.Type
def cast_stored(nil, _), do: {:ok, nil}
def cast_stored(value, _) do
Ecto.Type.load(:string, value)
end
@impl Ash.Type
def dump_to_native(nil, _), do: {:ok, nil}
def dump_to_native(value, _) do
Ecto.Type.dump(:string, value)
end
end