In Ecto.Changeset — Ecto v3.11.1 there is a part which says:
The
:delete
option in particular must be used carefully as it would allow users to delete any associated data. If you need deletion, it is often preferred to add a separate boolean virtual field to the changeset function that will allow you to manually mark it for deletion, as in the example below: […]
defmodule Comment do
use Ecto.Schema
import Ecto.Changeset
schema "comments" do
field :body, :string
field :delete, :boolean, virtual: true
end
def changeset(comment, params) do
cast(comment, params, [:body, :delete])
|> maybe_mark_for_deletion
end
defp maybe_mark_for_deletion(changeset) do
if get_change(changeset, :delete) do
%{changeset | action: :delete}
else
changeset
end
end
end
However, this example is incomplete and I am having trouble applying that.
Carrying on with the comment theme, If I have this as the schema that inserts it with cast_assoc
, where can I mark it as deleted? :
(I know it’s weird to have one comment but that’s the type of relationship I’m using in my actual code, so I want to keep the example similar)
defmodule Post do
use Ecto.Schema
import Ecto.Changeset
schema "posts" do
field(:title, :string)
field(:body, :string)
has_one(:comment, Comment)
end
def update_changeset(post, attrs) do
post
|> Repo.preload(:comment)
|> cast(attrs, [:title, :body])
|> cast_assoc(:comment, required: true, on_replace: :nilify)
end
end