View Source EctoModel.SoftDelete (EctoModel v0.0.1)
Module responsible for allowing your schemas to opt into soft delete functionality.
Usage
There are two things that need to happen in order to make a schema soft deletable:
You need to ensure your
MyApp.Repo
module is using theEctoMiddleware
behaviour, and you add theEctoModel.SoftDelete
middleware to themiddleware/2
callback before theEctoMiddleware.Super
middleware.This will enable
EctoModel.SoftDelete
to raise errors if users try to hard delete records when schemas have opted into soft deletes.In future, we may add support for automatically delegating hard delete operations to transparently behave transparently as soft deletes in an opt in basis.
You can also optionally add the following code to your
MyApp.Repo
module to enable easy soft delete operations:def soft_delete!(resource, opts \ []) do EctoModel.SoftDelete.soft_delete!(resource, Keyword.put(opts, :repo, __MODULE__)) end def soft_delete(resource, opts \ []) do EctoModel.SoftDelete.soft_delete(resource, Keyword.put(opts, :repo, __MODULE__)) end
You need to
use EctoModel.SoftDelete
in your schema, and configure thefield
andtype
options.The specified field and type must match what is defined on said schema, though there are compile time validations provided for you to ensure this remains in sync with your schema's natural evolution.
Additionally, if your schema also opts into implementing the
EctoModel.Queryable
behaviour, we automatically provide abase_query/0
implementation to will apply the neccessary filters to automatically filter out soft deleted records from query results.If you need to specify a custom
base_query/0
implementation, you can do so while still inheriting the default behaviour provided when using this module by callingsuper()
in your custom implementation like so:@impl EctoModel.Queryable def base_query do from x in ^super(), where: x.show_by_default != false end
A full example of how to use EctoModel.SoftDelete
is as follows:
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app
use EctoMiddleware
def middleware(_resource, _resolution) do
[EctoModel.SoftDelete, EctoMiddleware.Super]
end
end
defmodule MyApp.User do
use Ecto.Schema
use EctoModel.SoftDelete, field: :deleted_at, type: :utc_datetime
schema "users" do
field(:name, :string)
field(:email, :string)
field(:deleted_at, :utc_datetime)
end
end
Summary
Functions
After compile hook responsible for validating that a schema is properly configured for soft deletes.
Persists the configuration for soft deletes on the schema, as well as providing a default impl. for EctoModel.Queryable.base_query/0
.
Given a schema that has been configured to implement soft deletes, this function will apply the neccessary filters to the query to ensure that soft deleted records are not included in the result set.
Will soft delete a given resource, and persist the changes to the database, based on that resource's configured soft delete field and type.
See Ecto.Repo.soft_delete/2
for more information.
Types
@type soft_delete_type() :: :utc_datetime | :datetime | :boolean
Functions
After compile hook responsible for validating that a schema is properly configured for soft deletes.
Persists the configuration for soft deletes on the schema, as well as providing a default impl. for EctoModel.Queryable.base_query/0
.
@spec apply_filter!(schema :: module(), query :: Ecto.Query.t() | atom()) :: Ecto.Query.t()
Given a schema that has been configured to implement soft deletes, this function will apply the neccessary filters to the query to ensure that soft deleted records are not included in the result set.
Note that the strategy used for soft deletes is determined by the type
option when use
-ing EctoModel.SoftDelete
,
and we will apply the appropriate filter against the field
option when use
-ing EctoModel.SoftDelete
.
For example, if a schema is configured to implement soft deletes like so:
defmodule MyApp.User do
use Ecto.Schema
use EctoModel.SoftDelete, field: :deleted_at, type: :utc_datetime
schema "users" do
field(:name, :string)
field(:email, :string)
field(:deleted_at, :utc_datetime)
end
end
Then the apply_filter!/2
function will apply the following filter to the query:
from(x in query, where: is_nil(x.deleted_at))
However, if the schema is configured to implement soft deletes like so:
defmodule MyApp.User do
use Ecto.Schema
use EctoModel.SoftDelete, field: :deleted, type: :boolean
schema "users" do
field(:name, :string)
field(:email, :string)
field(:deleted, :boolean)
end
end
Then the apply_filter!/2
function will apply the following filter to the query:
from(x in query, where: is_nil(x.deleted) or x.deleted == false)
Will soft delete a given resource, and persist the changes to the database, based on that resource's configured soft delete field and type.
Will raise if given an entity that does not opt into soft deletes.
See Ecto.Repo.soft_delete/2
for more information.