Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Modify Value In Changeset - Elixir?

I am new to phoenix framework,lets say i have a model like follow with changeset

schema "users" do
 field :name, :string
 field :email, :string
 field :countryCode, :string
 field :phone, :string
end

def changeset_user_register(struct, params \\%{}) do
  struct
  |> cast(params, [:name, :email, :countryCode, :phone])
  |> validate_required(:name, [message: "Name Must Not Be Empty"])
  |> validate_required(:countryCode, [message: "countryCode Must Not Be Empty"])
  |> validate_required(:phone, [message: "Phone Number Must Not Be Empty"])
  |> valid_phone_number
end

params from form looks like %{name: 'elixir', countryCode: 'IN', phone: '97989*****'}

i am currently using ex_phone_number to validate phone number, my custom validator valid_phone_number looks like follow

defp valid_phone_number(struct) do
countryCode = get_field(struct, :countryCode) #get_field used to get values from struct
phone = get_field(struct, :phone)
case ExPhoneNumber.parse(phone, countryCode) do
  {:ok, phone_number} ->
    if ExPhoneNumber.is_valid_number?(phone_number) do
      e156_number = ExPhoneNumber.format(phone_number, :e164)
      %{struct | phone: e156_number}
      struct
    else
      add_error(struct, :phone, "Invalid Phone Number")
    end
  {:error, phone_number}->
    struct
 end
end

Instead of storing countryCode and phone in differnt column, I am trying to store e164 format number to my database so i modify the number e156_number = ExPhoneNumber.format(phone_number, :e164)in changeset after checking phone number is valid.when i trying to update phone in struct like follow %{struct | phone: e156_number} value is not updating instead it stores value returned from form %{phone: '97989*****'}, what mistake i made here and how can i remove countryCode also in changeset?

like image 934
Hari Avatar asked Apr 01 '17 06:04

Hari


1 Answers

To modify a value in a changeset, you should to use Ecto.Changeset.put_change/3. So, your if should look like:

if ExPhoneNumber.is_valid_number?(phone_number) do
  e156_number = ExPhoneNumber.format(phone_number, :e164)
  put_change(struct, :phone, e156_number)
else
  add_error(struct, :phone, "Invalid Phone Number")
end

Sidenote: valid_phone_number here is actually receiving an Ecto.Changeset, not the model Struct (technically the Ecto.Changeset is also an Elixir Struct but it's not your User struct), so changeset would be a better name for that variable.

like image 114
Dogbert Avatar answered Nov 19 '22 06:11

Dogbert