Hello,
I have a User structure that can have multiple accounts (has_many) and can be in multiple team through this accounts (many to many), as you can see below:
schema "user" do
...
has_many :accounts, Account
many_to_many(
:teams,
Team,
join_through: Account
)
timestamps()
end
And since I’m building basic CRUD operations for all entities of my application, I need to tell the user why he can’t delete his User (because there are still associated Accounts to it). But I can’t find a way to do this without try catching this way:
try do
Repo.delete(user)
rescue
Ecto.ConstraintError ->
{:error, "In order to delete an user, you must first delete it's associated accounts"}
end
But this is bad for 2 reasons, first is that it’s not standard that we use in our applications try catch (or erlang world), and second is that if I have more than one foreign constraint in any of my entities, I can’t tell which of them resulted in error.
I have tried all the possible ways found in documentation, for example:
on deletion:
Repo.get(User, user.id)
|> Ecto.Changeset.change
|> Ecto.Changeset.no_assoc_constraint(:accounts)
|> Repo.delete()
on changeset validation:
user
|> Ecto.Changeset.no_assoc_constraint(:accounts)
user
|> foreign_key_constraint(:accounts, name: "johan_sports_team_users_user_id_9294a0f7_fk_auth_user_id")
I tried many variations of this, but nothing seems to help, in the end I always get:
** (Ecto.ConstraintError) constraint error when attempting to delete struct:
* johan_sports_team_users_user_id_9294a0f7_fk_auth_user_id (foreign_key_constraint)
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.
Does anyone know a better solution for this?