Ecto can call Repo.delete/2 internally during association management, for
example through cast_assoc/3 or put_assoc/4 when an association uses a
delete-triggering on_replace strategy such as :delete or
:delete_if_exists.
Lazarus intercepts that flow:
- If the child schema has a
deleted_atfield and the parent schema does not opt that association into@hard_delete_on_replace, it is soft-deleted - Otherwise, it is hard-deleted
That means delete-triggering on_replace flows stay data-preserving whenever
the child schema is soft-delete-aware, but keep the default hard-delete
behaviour when they are not.
Forcing hard-delete for specific associations
The @hard_delete_on_replace attribute on the parent schema overrides the
soft-delete behavior, forcing hard-deletion even for schemas that have
deleted_at.
@hard_delete_on_replace [:ratings]
schema "posts" do
# Default: soft-deleted (Comment has deleted_at)
has_many :comments, Comment, on_replace: :delete_if_exists
# Override: hard-deleted (even though Rating has deleted_at)
has_many :ratings, Rating, on_replace: :delete_if_exists
end