bobthedeveloper
bobthedeveloper

Reputation: 3783

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.

Upvotes: 4

Views: 1280

Answers (1)

ventsislaf
ventsislaf

Reputation: 1671

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.

Upvotes: 3

Related Questions