Skip to content

Commit

Permalink
chore: generalize embed type __source__ logic
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Oct 17, 2023
1 parent c12f24d commit eca3b84
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 85 deletions.
92 changes: 8 additions & 84 deletions lib/ash/changeset/changeset.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1311,18 +1311,14 @@ defmodule Ash.Changeset do
end

defp set_lazy_defaults(changeset, type) do
attributes = Ash.Resource.Info.attributes(changeset.resource)

changeset
|> set_lazy_non_matching_defaults(attributes, type)
|> set_lazy_matching_defaults(attributes, type)
|> set_lazy_non_matching_defaults(type)
|> set_lazy_matching_defaults(type)
end

defp set_lazy_non_matching_defaults(changeset, attributes, type) do
attributes
|> Enum.filter(fn attribute ->
!attribute.match_other_defaults? && get_default_fun(attribute, type)
end)
defp set_lazy_non_matching_defaults(changeset, type) do
changeset.resource
|> Ash.Resource.Info.lazy_non_matching_default_attributes(type)
|> Enum.reduce(changeset, fn attribute, changeset ->
if changing_attribute?(changeset, attribute.name) do
changeset
Expand All @@ -1336,23 +1332,9 @@ defmodule Ash.Changeset do
end)
end

defp get_default_fun(attribute, :create) do
if is_function(attribute.default) or match?({_, _, _}, attribute.default) do
attribute.default
end
end

defp get_default_fun(attribute, :update) do
if is_function(attribute.update_default) or match?({_, _, _}, attribute.update_default) do
attribute.update_default
end
end

defp set_lazy_matching_defaults(changeset, attributes, type) do
attributes
|> Enum.filter(fn attribute ->
attribute.match_other_defaults? && get_default_fun(attribute, type)
end)
defp set_lazy_matching_defaults(changeset, type) do
changeset.resource
|> Ash.Resource.Info.lazy_matching_default_attributes(type)
|> Enum.group_by(fn attribute ->
case type do
:create ->
Expand Down Expand Up @@ -1386,64 +1368,6 @@ defmodule Ash.Changeset do
end)
end

# defp set_lazy_defaults(changeset, type) do
# changeset
# |> set_lazy_non_matching_defaults(type)
# |> set_lazy_matching_defaults(type)
# end

# defp set_lazy_non_matching_defaults(changeset, type) do
# changeset.resource
# |> Ash.Resource.Info.lazy_matching_default_attributes(type)
# |> Enum.reduce(changeset, fn attribute, changeset ->
# if changing_attribute?(changeset, attribute.name) do
# changeset
# else
# changeset
# |> force_change_attribute(attribute.name, default(type, attribute))
# |> Map.update!(:defaults, fn defaults ->
# [attribute.name | defaults]
# end)
# end
# end)
# end

# defp set_lazy_matching_defaults(changeset, type) do
# changeset.resource
# |> Ash.Resource.Info.lazy_matching_default_attributes(type)
# |> Enum.group_by(fn attribute ->
# case type do
# :create ->
# attribute.default

# :update ->
# attribute.update_default
# end
# end)
# |> Enum.reduce(changeset, fn {default_fun, attributes}, changeset ->
# default_value =
# case default_fun do
# function when is_function(function) ->
# function.()

# {m, f, a} when is_atom(m) and is_atom(f) and is_list(a) ->
# apply(m, f, a)
# end

# Enum.reduce(attributes, changeset, fn attribute, changeset ->
# if changing_attribute?(changeset, attribute.name) do
# changeset
# else
# changeset
# |> force_change_attribute(attribute.name, default_value)
# |> Map.update!(:defaults, fn defaults ->
# [attribute.name | defaults]
# end)
# end
# end)
# end)
# end

defp default(:create, %{default: {mod, func, args}}), do: apply(mod, func, args)
defp default(:create, %{default: function}) when is_function(function, 0), do: function.()
defp default(:create, %{default: value}), do: value
Expand Down
4 changes: 4 additions & 0 deletions lib/ash/embeddable_type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,10 @@ defmodule Ash.EmbeddableType do
end
end

def include_source(changeset, constraints) do
Keyword.put(constraints, :__source__, changeset)
end

def prepare_change_array(_old_values, nil, _constraints) do
{:ok, nil}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/ash/type/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Ash.Type.Helpers do

def cast_input(type, value, constraints, changeset, return_value?) do
value = handle_indexed_maps(type, value)
constraints = constraints ++ [{:__source__, changeset}]
constraints = Ash.Type.include_source(type, changeset, constraints)

case Ash.Type.cast_input(type, value, constraints) do
{:ok, value} ->
Expand Down
15 changes: 15 additions & 0 deletions lib/ash/type/type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ defmodule Ash.Type do

@callback storage_type() :: Ecto.Type.t()
@callback storage_type(constraints) :: Ecto.Type.t()
@callback include_source(constraints, Ash.Changeset.t()) :: constraints
@doc """
Useful for typed data layers (like ash_postgres) to instruct them not to attempt to cast input values.
Expand Down Expand Up @@ -219,6 +220,7 @@ defmodule Ash.Type do
array_constraints: 0,
dump_to_embedded: 2,
dump_to_embedded_array: 2,
include_source: 2,
load: 4
]

Expand Down Expand Up @@ -823,6 +825,15 @@ defmodule Ash.Type do
type.equal?(left, right)
end

@spec include_source(t(), Ash.Changeset.t(), constraints()) :: constraints()
def include_source({:array, type}, changeset, constraints) do
include_source(type, changeset, constraints)
end

def include_source(type, changeset, constraints) do
type.include_source(changeset, constraints)
end

@spec load(
type :: Ash.Type.t(),
values :: list(term),
Expand Down Expand Up @@ -1007,6 +1018,9 @@ defmodule Ash.Type do
@impl true
def prepare_change(_old_value, new_value, _constraints), do: {:ok, new_value}

@impl true
def include_source(_, constraints), do: constraints

@impl true
def array_constraints do
unquote(@array_constraints)
Expand All @@ -1022,6 +1036,7 @@ defmodule Ash.Type do

defoverridable constraints: 0,
init: 1,
include_source: 2,
describe: 1,
embedded?: 0,
ecto_type: 0,
Expand Down

0 comments on commit eca3b84

Please sign in to comment.