Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique constraint with embedded schema

Is there any way to get a unique constraint working for an embedded schema?

The given code below gives the exception:

cannot add constraint to changeset because it does not have a source

Field name comes from the schema persons and field email from accounts

Schema:

embedded_schema do
    field :name
    field :email
end

Changeset:

struct
  |> Ecto.Changeset.cast(params, [:name, :email])
  |> Ecto.Changeset.validate_required([:name, :email])
  |> Ecto.Changeset.unique_constraint(:email)

I tried to give the schema accounts in as parameter but with no success.

like image 810
bobthedeveloper Avatar asked Sep 11 '25 07:09

bobthedeveloper


1 Answers

Is there any way to get a unique constraint working for an embedded schema?

The short answer is no.

Ecto's unique_constraint relies on the database. In order to work, you need to add unique index for the given field. The constraint will only convert the database error into a changeset error. You can read more in the docs https://hexdocs.pm/ecto/Ecto.Changeset.html#unique_constraint/3

Edit:

Using embedded_schema means that you cannot have unique index on the email "field", because it's not a field itself. Ecto uses a single jsonb field to store the embedded data.

You could create an Account schema which is related to the database. Then you could manually map the data to an account changeset and use unique_constraint on it.

like image 99
ventsislaf Avatar answered Sep 13 '25 03:09

ventsislaf