I’m trying to validate the length of a phone number in elixir’s ecto, below is the code I’m using
defmodule MyApp.Phone_number_Otp do
use Ecto.Schema
import Ecto.Changeset
schema "phone_num_otps" do
field :otp_code, :integer
field :phone_num, :string
field :phone_num_verified, :boolean, default: false
field :phone_num_verified_at, :naive_datetime
timestamps()
end
@min_chars 10
@max_chars 13
@doc false
def changeset(phone_number__otp, attrs) do
phone_number__otp
|> cast(attrs, [:phone_num, :otp_code, :phone_num_verified_at, :phone_num_verified])
# |> validate_required([:phone_num, :otp_code, :phone_num_verified_at, :phone_num_verified])
|> validate_required([:phone_num])
|> validate_length(:phone_num, min: @min_chars, max: @max_chars)
# |> validate_inclusion(:phone_num, 10..13)
|> unique_constraint(:phone_num)
end
end
However, even when I post phone number’s length less than 10 chars and greater than 13, the changeset is able to insert data into postgres db… I’m still learning to work in ecto, so any help would be greatly appreciated. Please correct me where I’m going wrong.
Thanks
Can we see your calling code where you perform the insert?
I’d also suggest to inspect the changeset IO.inspect changeset
and check its :valid?
and :errors
fields.
Thank you @mathieuprog for the reply, yes the changeset is not valid, but I’m not sure how the phone number is being inserted in to the database. Here’s the report -
#Ecto.Changeset<
action: nil,
changes: %{},
errors: [phone_num: {"can't be blank", [validation: :required]}],
data: #MyApp.Phone_number_Otp<>,
valid?: false
>
Looks good. I would now print the data IO.inspect changeset.data
and you can also show the code that passes the changeset to the Repo.insert
function.
Here’s the output of data -
MyApp.Phone_number_Otp{
__meta__: #Ecto.Schema.Metadata<:built, "phone_num_otps">,
id: nil,
inserted_at: nil,
otp_code: nil,
phone_num: nil,
phone_num_verified: false,
phone_num_verified_at: nil,
updated_at: nil
}
I’m inserting the data into Postgres using the following code -
otp_code = Enum.random(10000..99999)
user = MyApp.Phone_number_Otp.changeset(%MyApp.Phone_number_Otp{}, params)
IO.inspect user.data
Repo.insert(%Phone_number_Otp{phone_num: phone_num, otp_code: otp_code})
user = MyApp.Phone_number_Otp.changeset(%MyApp.Phone_number_Otp{}, params)
IO.inspect user.data
Well you’re not passing the changeset (that has the invalid state) to insert
How can I do that, I’m still a noob in changeset stuff?
alias MyApp.PhoneNumberOtp
user_changeset = PhoneNumberOtp.changeset(%PhoneNumberOtp{}, params)
Repo.insert(user_changeset)
I would suggest to learn a little more regarding this topic; it’s really essential to understand how Changesets work when working with Ecto.
1 Like
Thanks man, I really appreciate your help… and also learn some more about this. Have a nice day and stay safe!
1 Like