Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ecto validate_required of either of two attributes

Tags:

ecto

What's the best way to do a validation of the presence of either of two attributes for a changeset?

The validation should only fail if neither of the two attributes is provided

e.g. consider a User model with attributes :name, :uid, :email, :phone

  • :name always needs to be present
  • either :email or :uid should be present
  • :phone is optional

Would this work?

  def changeset(struct, params \\ %{}) do
    struct
      |> cast(params, [:name,:email,:uid,:phone])
      |> validate_required([:name, :email]) || validate_required([:name, :uid]
    end
  end
like image 978
Tilo Avatar asked Oct 19 '25 10:10

Tilo


1 Answers

You may start with something like:

def changeset(struct, params \\ %{}) do
  struct
    |> cast(params, ~w(name email uid phone)a)
    |> validate_required(:name)
    |> validate_required_params(params)
  end
end

def validate_required_params(changeset, %{"uid" => _}) do
  changeset
  |> validate_required(:uid)
end

def validate_required_params(changeset, %{"email" => _}) do
  changeset
  |> validate_required(:email)
end

def validate_required_params(changeset, _params) do
  changeset
  |> add_error(:params, "either :uid or :email is required")
end

But you need to also check for example if both uid and email are provided. What in such case?

like image 101
Kamil Lelonek Avatar answered Oct 22 '25 06:10

Kamil Lelonek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!