Skip to content

Commit

Permalink
fix: don't load nil values for runtime types
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Jun 12, 2023
1 parent d47dbe2 commit 0a677cc
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 33 deletions.
81 changes: 52 additions & 29 deletions lib/ash/actions/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -303,13 +303,13 @@ defmodule Ash.Actions.Helpers do
{:ok, result} ->
{:cont, {:ok, [result | results]}}

other ->
{:halt, other}
{:error, error} ->
{:halt, {:error, error}}
end
end)
|> case do
{:ok, results} -> {:ok, Enum.reverse(results)}
other -> other
{:error, error} -> {:error, error}
end
end
end
Expand Down Expand Up @@ -356,42 +356,65 @@ defmodule Ash.Actions.Helpers do
defp do_load_runtime_types(record, select, calculations) do
select
|> Enum.reduce_while({:ok, record}, fn attr, {:ok, record} ->
case Ash.Type.cast_stored(attr.type, Map.get(record, attr.name), attr.constraints) do
{:ok, value} ->
{:cont, {:ok, Map.put(record, attr.name, value)}}

other ->
{:halt, other}
case Map.get(record, attr.name) do
nil ->
{:cont, {:ok, record}}

value ->
case Ash.Type.cast_stored(
attr.type,
value,
attr.constraints
) do
{:ok, value} ->
{:cont, {:ok, Map.put(record, attr.name, value)}}

:error ->
{:halt, {:error, message: "is invalid", field: attr.name}}
end
end
end)
|> case do
{:ok, record} ->
Enum.reduce_while(calculations, {:ok, record}, fn {name, calc}, {:ok, record} ->
case calc.load do
nil ->
case Ash.Type.cast_stored(
calc.type,
Map.get(record.calculations || %{}, calc.name),
Map.get(calc, :constraints, [])
) do
{:ok, value} ->
{:cont, {:ok, Map.update!(record, :calculations, &Map.put(&1, name, value))}}

other ->
{:halt, other}
case Map.get(record.calculations || %{}, calc.name) do
nil ->
{:cont, {:ok, record}}

value ->
case Ash.Type.cast_stored(
calc.type,
value,
Map.get(calc, :constraints, [])
) do
{:ok, value} ->
{:cont,
{:ok, Map.update!(record, :calculations, &Map.put(&1, name, value))}}

:error ->
{:halt, {:error, message: "is invalid", field: calc.name}}
end
end

load ->
case Ash.Type.cast_stored(
calc.type,
Map.get(record, load),
Map.get(calc, :constraints, [])
) do
{:ok, casted} ->
{:cont, {:ok, Map.put(record, load, casted)}}

other ->
{:halt, other}
case Map.get(record, load) do
nil ->
{:cont, {:ok, record}}

value ->
case Ash.Type.cast_stored(
calc.type,
value,
Map.get(calc, :constraints, [])
) do
{:ok, casted} ->
{:cont, {:ok, Map.put(record, load, casted)}}

:error ->
{:halt, {:error, message: "is invalid", field: calc.name}}
end
end
end
end)
Expand Down
10 changes: 6 additions & 4 deletions lib/ash/actions/read.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,8 @@ defmodule Ash.Actions.Read do
{:ok, query} <-
Ash.DataLayer.offset(query, ash_query.offset, ash_query.resource),
{:ok, query} <- set_tenant(query, ash_query),
{:ok, query} <- Ash.DataLayer.lock(query, ash_query.lock, ash_query.resource),
{:ok, query} <-
Ash.DataLayer.lock(query, ash_query.lock, ash_query.resource),
{:ok, results} <-
run_query(
set_phase(ash_query, :executing),
Expand All @@ -1349,7 +1350,8 @@ defmodule Ash.Actions.Read do
aggregates_in_query,
calculations_in_query
),
:ok <- validate_get(results, ash_query.action, ash_query),
:ok <-
validate_get(results, ash_query.action, ash_query),
{:ok, results, after_notifications} <-
run_after_action(initial_query, results),
{:ok, count} <- maybe_await(count) do
Expand Down Expand Up @@ -1379,8 +1381,8 @@ defmodule Ash.Actions.Read do
%{valid?: false} = query ->
{:error, query.errors}

other ->
other
{:error, error} ->
{:error, error}
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/ash/type/type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ defmodule Ash.Type do

def cast_stored(type, term, constraints) do
type = get_type(type)

type.cast_stored(term, constraints)
end

Expand Down

0 comments on commit 0a677cc

Please sign in to comment.