Skip to content

Commit

Permalink
Recurse query and apply filtering directly as appropriate
Browse files Browse the repository at this point in the history
  • Loading branch information
Glen Holcomb committed Oct 30, 2024
1 parent 36ebba3 commit 35f3761
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/ecto/soft_delete_repo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,37 @@ defmodule Ecto.SoftDelete.Repo do
if has_include_deleted_at_clause?(query) || opts[:with_deleted] || !soft_deletable?(query) do
{query, opts}
else
query = from(x in query, where: is_nil(x.deleted_at))
query = filter_soft_deleted(query)
{query, opts}
end
end

# We need to check the entire query and apply filtering
# where appropriate. So, we recurse the query here and
# rebuild it with filtering where appropriate. This
# currently only considers the source and does not handle
# things like joins...
defp filter_soft_deleted(%Ecto.Query{from: %{source: {_schema, _module}}} = query) do
if Ecto.SoftDelete.Query.soft_deletable?(query) do
from(x in query, where: is_nil(x.deleted_at))
else
query
end
end

defp filter_soft_deleted(%Ecto.SubQuery{query: query} = sub) do
if Ecto.SoftDelete.Query.soft_deletable?(query) do
from(x in query, where: is_nil(x.deleted_at)) |> subquery()
else
sub
end
end

defp filter_soft_deleted(%Ecto.Query{from: from} = query) do
updated_from = %{from | source: filter_soft_deleted(from.source)}
%{query | from: updated_from}
end

# Checks the query to see if it contains a where not is_nil(deleted_at)
# if it does, we want to be sure that we don't exclude soft deleted records
defp has_include_deleted_at_clause?(%Ecto.Query{wheres: wheres}) do
Expand Down

0 comments on commit 35f3761

Please sign in to comment.