3
votes

i don't have experience with developing and this is not my first language, sorry for anything.

I'm working in an mobile app with the back end in Elixir/Phoenix, when a person wants to create a new account the system requires 5 information to create a new account (email, cpf, name, phone_number, password).

in my new registration flow I want to request only 2 data (Email and Password) and later using the application the user can complete the missing data, so my system has to be able to create an account with this data being null.

First i went to my structure database to check if it was not allowing the data to be null, how you can see bellow it's not happening:

CREATE TABLE users (
  id bigint NOT NULL,
  email character varying(255),
  cpf character varying(255),
  phone_number character varying(255),
  password character varying(255),
  inserted_at timestamp without time zone NOT NULL,
  updated_at timestamp without time zone NOT NULL,
  name character varying(255)
);

so I went to check my user.ex file to see if the function that does the data validation was not allowing them to be null, and i found this:

def changeset(%User{} = user, attrs) do
  user
  |> cast(attrs, [:email, :cpf, :name, :phone_number, :password])
  |> validate_required([:email, :cpf, :name, :phone_number, :password])
  |> validate_format(:email, ~r/^[A-Za-z0-9._%+-+']+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
  |> validate_format(:cpf, ~r/([0-9]{2}[\.]?[0-9]{3}[\.]?[0-9]{3}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}[\.]?[0-9]{3}[\.]?[0-9]{3}[-]?[0-9]{2})/)
  |> validate_cpf(:cpf)
  |> unique_constraint(:email)
  |> unique_constraint(:cpf)
  |> unique_constraint(:phone_number)
  |> update_password_hash()
  |> update_activation_code()
end

I believe I need to change this function to allow the system to create an account without all this data and after having made the account the user can complete their data with from within the app but I'm not sure how I can do this, can anybody help me ?

2

2 Answers

3
votes

If the field is not required, you should remove it from validate_required.

So your changeset function should become

def changeset(%User{} = user, attrs) do
  user
  |> cast(attrs, [:email, :cpf, :name, :phone_number, :password])
  |> validate_required([:email, :password])
  |> validate_format(:email, ~r/^[A-Za-z0-9._%+-+']+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)
  |> validate_format(:cpf, ~r/([0-9]{2}[\.]?[0-9]{3}[\.]?[0-9]{3}[\/]?[0-9]{4}[-]?[0-9]{2})|([0-9]{3}[\.]?[0-9]{3}[\.]?[0-9]{3}[-]?[0-9]{2})/)
  |> validate_cpf(:cpf)
  |> unique_constraint(:email)
  |> unique_constraint(:cpf)
  |> unique_constraint(:phone_number)
  |> update_password_hash()
  |> update_activation_code()
end
2
votes

All you need to do is change the call to the validate_required method to remove the fields you want to be optional:

|> validate_required([:email, :password])

If you want to learn more about what these function calls do, you can read the Phoenix framework guide about Ecto (particularly, the section on Changesets and Validations).