mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
improvement: improve the behavior of defaults
functional defaults are added at action time, others are added directly into the changeset
This commit is contained in:
parent
d4b27d5d4e
commit
f3c85da268
5 changed files with 28 additions and 33 deletions
|
@ -76,7 +76,7 @@ defmodule Ash.Actions.Create do
|
|||
else
|
||||
Ash.Changeset.for_create(changeset, action.name, %{}, actor: actor)
|
||||
end
|
||||
|> Ash.Changeset.set_defaults(:create)
|
||||
|> Ash.Changeset.set_defaults(:create, true)
|
||||
|> Ash.Changeset.cast_arguments(action)
|
||||
end
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ defmodule Ash.Actions.Update do
|
|||
else
|
||||
Ash.Changeset.for_update(changeset, action.name, %{}, actor: actor)
|
||||
end
|
||||
|> Ash.Changeset.set_defaults(:update)
|
||||
|> Ash.Changeset.set_defaults(:update, true)
|
||||
|> Ash.Changeset.cast_arguments(action)
|
||||
end
|
||||
|
||||
|
|
|
@ -280,11 +280,6 @@ defmodule Ash.Changeset do
|
|||
tenant: [
|
||||
type: :any,
|
||||
doc: "set the tenant on the changeset"
|
||||
],
|
||||
defaults: [
|
||||
type: :any,
|
||||
doc:
|
||||
"A list of attributes and arguments to apply defaults for. Defaults to: []. Any unset defaults are set when the action is called."
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -450,7 +445,7 @@ defmodule Ash.Changeset do
|
|||
|> validate_relationships_accepted(action)
|
||||
|> cast_arguments(action, opts[:defaults], true)
|
||||
|> run_action_changes(action, opts[:actor])
|
||||
|> set_defaults(changeset.action_type, opts[:defaults] || [])
|
||||
|> set_defaults(changeset.action_type, false)
|
||||
|> add_validations()
|
||||
|> require_values(changeset.action_type)
|
||||
|> mark_validated(action.name)
|
||||
|
@ -585,13 +580,16 @@ defmodule Ash.Changeset do
|
|||
end
|
||||
|
||||
@doc false
|
||||
def set_defaults(changeset, action_type, keys \\ :all)
|
||||
def set_defaults(changeset, action_type, lazy? \\ false)
|
||||
|
||||
def set_defaults(changeset, :create, keys) do
|
||||
def set_defaults(changeset, :create, lazy?) do
|
||||
changeset.resource
|
||||
|> Ash.Resource.Info.attributes()
|
||||
|> Enum.filter(&(not is_nil(&1.default)))
|
||||
|> Enum.filter(&(keys == :all || &1.name in keys))
|
||||
|> Enum.filter(fn attribute ->
|
||||
lazy? or
|
||||
not (is_function(attribute.default) or match?({_, _, _}, attribute.default))
|
||||
end)
|
||||
|> Enum.reduce(changeset, fn attribute, changeset ->
|
||||
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
||||
default(:create, attribute)
|
||||
|
@ -599,11 +597,14 @@ defmodule Ash.Changeset do
|
|||
end)
|
||||
end
|
||||
|
||||
def set_defaults(changeset, :update, keys) do
|
||||
def set_defaults(changeset, :update, lazy?) do
|
||||
changeset.resource
|
||||
|> Ash.Resource.Info.attributes()
|
||||
|> Enum.filter(&(not is_nil(&1.update_default)))
|
||||
|> Enum.filter(&(keys == :all || &1.name in keys))
|
||||
|> Enum.filter(fn attribute ->
|
||||
lazy? or
|
||||
not (is_function(attribute.update_default) or match?({_, _, _}, attribute.update_default))
|
||||
end)
|
||||
|> Enum.reduce(changeset, fn attribute, changeset ->
|
||||
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
||||
default(:update, attribute)
|
||||
|
|
|
@ -217,11 +217,6 @@ defmodule Ash.Query do
|
|||
tenant: [
|
||||
type: :any,
|
||||
doc: "set the tenant on the query"
|
||||
],
|
||||
defaults: [
|
||||
type: :any,
|
||||
doc:
|
||||
"A list of arguments to apply defaults for. Defaults to: []. Any unset defaults are set when the action is called."
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -257,7 +252,7 @@ defmodule Ash.Query do
|
|||
|> cast_params(action, args)
|
||||
|> run_preparations(action, opts[:actor])
|
||||
|> add_action_filters(action, opts[:actor])
|
||||
|> cast_arguments(action, opts[:defaults], true)
|
||||
|> cast_arguments(action, true)
|
||||
else
|
||||
add_error(query, :action, "No such action #{action_name}")
|
||||
end
|
||||
|
@ -801,22 +796,18 @@ defmodule Ash.Query do
|
|||
end
|
||||
|
||||
@doc false
|
||||
def cast_arguments(query, action, defaults \\ :all, only_supplied? \\ false) do
|
||||
def cast_arguments(query, action, only_supplied? \\ false) do
|
||||
action.arguments
|
||||
|> Enum.reject(& &1.private?)
|
||||
|> Enum.reject(&(only_supplied? && match?({:ok, _}, fetch_argument(query, &1.name))))
|
||||
|> Enum.reduce(query, fn argument, new_query ->
|
||||
{ignore_nil_check, value} =
|
||||
if defaults == :all || argument.name in (defaults || []) do
|
||||
{false, get_argument(query, argument.name) || argument_default(argument.default)}
|
||||
else
|
||||
value = get_argument(query, argument.name)
|
||||
value = get_argument(query, argument.name)
|
||||
|
||||
if argument_default(argument.default) do
|
||||
{true, value}
|
||||
else
|
||||
{false, value}
|
||||
end
|
||||
{ignore_nil_check, value} =
|
||||
if argument_default(argument.default) do
|
||||
{true, value}
|
||||
else
|
||||
{false, value}
|
||||
end
|
||||
|
||||
cond do
|
||||
|
|
|
@ -82,12 +82,12 @@ defmodule Ash.Resource.Attribute do
|
|||
update_default: [
|
||||
type: {:custom, Ash.OptionsHelpers, :default, []},
|
||||
doc:
|
||||
"A zero argument function, an {mod, fun, args} triple or a value. If no value is provided for the attribute on update, this value is used."
|
||||
"A zero argument function, an {mod, fun, args} triple or a value. `Ash.Changeset.for_update/4` sets the default in the changeset if a value is not provided."
|
||||
],
|
||||
default: [
|
||||
type: {:custom, Ash.OptionsHelpers, :default, []},
|
||||
doc:
|
||||
"A zero argument function, an {mod, fun, args} triple or a value. If no value is provided for the attribute on create, this value is used."
|
||||
"A zero argument function, an {mod, fun, args} triple or a value. `Ash.Changeset.for_create/4` sets the default in the changeset if a value is not provided."
|
||||
],
|
||||
description: [
|
||||
type: :string,
|
||||
|
@ -106,7 +106,10 @@ defmodule Ash.Resource.Attribute do
|
|||
|> OptionsHelpers.set_default!(:writable?, false)
|
||||
|> OptionsHelpers.set_default!(:private?, true)
|
||||
|> OptionsHelpers.set_default!(:default, &DateTime.utc_now/0)
|
||||
|> OptionsHelpers.set_default!(:update_default, &DateTime.utc_now/0)
|
||||
|> OptionsHelpers.set_default!(
|
||||
:update_default,
|
||||
&DateTime.utc_now/0
|
||||
)
|
||||
|> OptionsHelpers.set_default!(:type, Ash.Type.UtcDatetimeUsec)
|
||||
|> OptionsHelpers.set_default!(:allow_nil?, false)
|
||||
|
||||
|
|
Loading…
Reference in a new issue