Public entrypoint for Lazarus.
Most applications interact with Lazarus in two layers:
use Lazarusin a Repo module to injectRepo.soft_delete*,Repo.hard_delete*, read-side filtering, and update behavior that skips soft-deleted rows- call the functions in this module when you want the same soft-delete behavior while passing the Repo module explicitly
This module is the repo-explicit API for Lazarus's soft-delete helpers.
Updates use Ecto Repo functions; use Lazarus makes Repo.update*, loaded
Repo.insert_or_update*, and Repo.update_all/3 skip soft-deleted rows by
default.
Lazarus.Repo documents the functions injected into a Repo by use Lazarus.
Basic usage
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app, adapter: Ecto.Adapters.Postgres
use Lazarus
endUse Lazarus.Schema in schemas that should support soft deletion:
defmodule MyApp.Post do
use Ecto.Schema
use Lazarus.Schema
schema "posts" do
soft_deletes()
end
endUse Lazarus.Migrations to add the matching columns:
defmodule MyApp.Repo.Migrations.AddSoftDeletesToPosts do
use Ecto.Migration
use Lazarus.Migrations
def change do
alter table(:posts) do
soft_deletes()
end
end
endWhere to read next
Lazarus.Repo- injected Repo functions anduse LazarusintegrationLazarus.Schema- schema helpers and schema-level cascade metadataLazarus.Migrations- migration helpers for adding matching columns- the HexDocs guides - workflow-oriented explanations of queries, cascading, and association replacement
Summary
Query helpers
Recursively applies Lazarus's read-side soft-delete filtering to an Ecto query.
Soft delete API
Soft-deletes a single struct or changeset with an explicit Repo module.
Soft-deletes a single struct or changeset and raises on failure.
Soft-deletes all rows matched by a schema-aware queryable.
Query helpers
Recursively applies Lazarus's read-side soft-delete filtering to an Ecto query.
This is the same query-rewriting step injected into Repos that use Lazarus for reads. Repo.update_all/3 uses the same recursive filtering
internally.
Returns
- a rewritten query when filtering is applied
- the original query unchanged when
with_deleted: trueis passed and the query shape is safe or explicitly allowed - non-query values unchanged
Options
:with_deleted- boolean controlling whether soft-delete filtering is bypassed for the whole query (accepted values:true,false; default:false):allow_raw_sql- boolean controlling whether raw SQL fragments are allowed (accepted values:true,false; default:false):allow_schema_less_sources- boolean controlling whether schema-less string table sources are allowed (accepted values:true,false; default:false)
Raises
ArgumentErrorwhen the query contains raw SQL fragments unlessallow_raw_sql: trueis passedArgumentErrorwhen the query contains schema-less root or join sources unlessallow_schema_less_sources: trueis passed
Examples
query =
from(post in Post, select: post.id)
Lazarus.deep_filter_soft_deleted(query, [])
Lazarus.deep_filter_soft_deleted(query, with_deleted: true)
Lazarus.deep_filter_soft_deleted(query, allow_raw_sql: true)
Lazarus.deep_filter_soft_deleted(query, allow_schema_less_sources: true)See the "Query Support" guide for the precise root, join, subquery, and CTE behaviors.
Soft delete API
Soft-deletes a single struct or changeset with an explicit Repo module.
This is the repo-explicit equivalent of Repo.soft_delete/2.
Returns
{:ok, struct}on success{:error, :not_found}when the row was already soft-deleted or no longer exists
Options
:reason- string reason persisted todeletion_reasonwhen the schema includes that field, ornil(default:nil):cascade- boolean controlling whether eligible associations are cascaded (accepted values:true,false; default:false):reload_after_delete- boolean controlling whether Lazarus reloads the soft-deleted struct from the database after deletion (accepted values:true,false; default: repo config:reload_after_delete, thenfalse). The default in-memory return avoids an additional database call and is faster, but may be less accurate than a fresh load; associations on the returned struct are reset toEcto.Association.NotLoaded. Loading after deletion is more accurate, but costs one additional database call.:skip_associations- list of association field names to skip during cascading, such as[:comments, :ratings]:cascade_depth- positive integer recursion cap for cascading (default:10)
Examples
{:ok, deleted_post} = Lazarus.soft_delete(MyApp.Repo, post)
{:ok, deleted_post} = Lazarus.soft_delete(MyApp.Repo, post, reason: "Deleted by user")
{:ok, deleted_post} = Lazarus.soft_delete(MyApp.Repo, post, reload_after_delete: true)
Soft-deletes a single struct or changeset and raises on failure.
This is the repo-explicit equivalent of Repo.soft_delete!/2.
Returns
- the deleted struct on success
Options
Accepts the same options as soft_delete/3.
Raises
ArgumentErrorwhen the row was already soft-deleted or no longer exists
Examples
deleted_post = Lazarus.soft_delete!(MyApp.Repo, post)
deleted_post = Lazarus.soft_delete!(MyApp.Repo, post, reason: "Moderator action")
deleted_post = Lazarus.soft_delete!(MyApp.Repo, post, reload_after_delete: true)
Soft-deletes all rows matched by a schema-aware queryable.
This is the repo-explicit equivalent of Repo.soft_delete_all/2.
Returns
{count, nil}when the query does not include aselect{count, returned}when the query includes aselect, matching the usual Ecto bulk-update return shape
Options
:reason- string reason persisted todeletion_reasonwhen the schema includes that field, ornil(default:nil):cascade- boolean controlling whether eligible associations are cascaded (accepted values:true,false; default:false):skip_associations- list of association field names to skip during cascading, such as[:comments, :ratings]:cascade_depth- positive integer recursion cap for cascading (default:10):allow_raw_sql- boolean controlling whether fragments are allowed in the bulk soft-delete query (accepted values:true,false; default:false):allow_schema_less_sources- boolean controlling whether schema-less joins and nested sources are allowed in the bulk soft-delete query (accepted values:true,false; default:false). The root source must still be schema-aware.
Query Requirements
- the query root must be schema-aware, such as
Postor{"posts", Post} - schema-less roots such as
from(row in "posts")are not supported - subquery roots such as
from(row in subquery(...))are not supported - schema-less joins and nested schema-less sources require
allow_schema_less_sources: true
See the "Query Support" guide for the full set of supported query shapes.
Examples
Lazarus.soft_delete_all(MyApp.Repo, Post)
Lazarus.soft_delete_all(
MyApp.Repo,
from(post in Post, where: post.author_id == ^author_id),
reason: "Bulk cleanup"
)