sharkmyster
How to handle constraint error when deleting record from adjacency list?
I’m using an adjacency list to store a hierarchy of categories. There can be many root categories each with many children/descendants.
defmodule WordSolverDal.Categories.Category do
use Ecto.Schema
import Ecto.Changeset
use Arbor.Tree,
foreign_key: :parent_id,
foreign_key_type: :integer
schema "categories" do
field(:name, :string)
field(:parent_id, :integer)
many_to_many(:answers, WordSolverDal.Answers.Answer, join_through: "answers_categories")
timestamps()
end
@required [:name]
@optional [:parent_id]
def changeset(category, attrs) do
category
|> cast(attrs, @required ++ @optional)
|> validate_required(@required)
|> validate_length(:name, min: 3)
|> unique_constraint(:name, name: :unique_categories_name_parent_id_null)
|> unique_constraint(:name, name: :unique_categories_name_parent_id)
end
end
The db throws a constraint error if a user tries to delete a record that has children due to the foreign key constraint on :parent_id.
constraint error when attempting to delete struct:
* "categories_parent_id_fkey" (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.
This error gives advice on how to handle the error without raising an exception but I don’t see how this could work. As I understand it, foreign_key_constraint/3 is typically used for insert/update change sets.
How can I attempt a delete and not raise an exception as described? Or should I just rescue the error?
Marked As Solved
ibarch
Maybe something like this would work?
defmodule WordSolverDal.Categories.Category do
schema "categories" do
has_many :descendant_categories, __MODULE__, foreign_key: :parent_id
end
end
def delete_category(category) do
category
|> Ecto.Changeset.change()
|> Ecto.Changeset.no_assoc_constraint(:descendant_categories,
name: "categories_parent_id_fkey",
message: "there is descendant categor[y|ies] associated with this one"
)
|> Repo.delete()
end
Also Liked
kokolegorille
Ok, it’s a plugin from here…
https://github.com/coryodaniel/arbor
You need to define something like this…
schema "categories" do
...
belongs_to :parent, __MODULE__
has_many :categories, __MODULE__
timestamps
end
otherwise it doesn’t know what categories are
=> and add foreign key, as @ibarch said
sharkmyster
This worked. Thank you.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









