(Ecto.ConstraintError) constraint error when attempting to delete struct

I have a parent, which has_many children. Children have a restrict constraint on the DB level: on_delete: :restrict. Thus the error does not come as a surprise. The surprise part is later:

If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `foreign_key_constraint/3` on your changeset with the constraint
`:name` as an option.

The changeset has not defined any constraint.

Now, how and where do I call foreign_key_constraint/3 when everything I do is actually Ecto.Repo.delete/2 for which no changeset is needed? I’d still prefer {:error, _something} being returned rather than having an exception risen

delete accepts changesets so you’d need to convert your struct to take advantage of it. Ecto.Changeset.change(struct) is the simplest way.

2 Likes

As @joey_the_snake hinted to, you can create a changeset by wrapping the parent struct into one using change/2.

Then you can call no_assoc_constraint/3 on the parent changeset. Now, when you delete, you will get an error in the changeset if there are any children attached to the parent.

3 Likes

Right. While I knew I could wrap the struct in a changeset, the foreign_key_constraint/3 suggestion was misleading. The no_assoc_constraint/3 does the trick neatly though. Thank you guys.

2 Likes