mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 21:43:02 +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
|
else
|
||||||
Ash.Changeset.for_create(changeset, action.name, %{}, actor: actor)
|
Ash.Changeset.for_create(changeset, action.name, %{}, actor: actor)
|
||||||
end
|
end
|
||||||
|> Ash.Changeset.set_defaults(:create)
|
|> Ash.Changeset.set_defaults(:create, true)
|
||||||
|> Ash.Changeset.cast_arguments(action)
|
|> Ash.Changeset.cast_arguments(action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ defmodule Ash.Actions.Update do
|
||||||
else
|
else
|
||||||
Ash.Changeset.for_update(changeset, action.name, %{}, actor: actor)
|
Ash.Changeset.for_update(changeset, action.name, %{}, actor: actor)
|
||||||
end
|
end
|
||||||
|> Ash.Changeset.set_defaults(:update)
|
|> Ash.Changeset.set_defaults(:update, true)
|
||||||
|> Ash.Changeset.cast_arguments(action)
|
|> Ash.Changeset.cast_arguments(action)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -280,11 +280,6 @@ defmodule Ash.Changeset do
|
||||||
tenant: [
|
tenant: [
|
||||||
type: :any,
|
type: :any,
|
||||||
doc: "set the tenant on the changeset"
|
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)
|
|> validate_relationships_accepted(action)
|
||||||
|> cast_arguments(action, opts[:defaults], true)
|
|> cast_arguments(action, opts[:defaults], true)
|
||||||
|> run_action_changes(action, opts[:actor])
|
|> run_action_changes(action, opts[:actor])
|
||||||
|> set_defaults(changeset.action_type, opts[:defaults] || [])
|
|> set_defaults(changeset.action_type, false)
|
||||||
|> add_validations()
|
|> add_validations()
|
||||||
|> require_values(changeset.action_type)
|
|> require_values(changeset.action_type)
|
||||||
|> mark_validated(action.name)
|
|> mark_validated(action.name)
|
||||||
|
@ -585,13 +580,16 @@ defmodule Ash.Changeset do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@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
|
changeset.resource
|
||||||
|> Ash.Resource.Info.attributes()
|
|> Ash.Resource.Info.attributes()
|
||||||
|> Enum.filter(&(not is_nil(&1.default)))
|
|> 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 ->
|
|> Enum.reduce(changeset, fn attribute, changeset ->
|
||||||
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
||||||
default(:create, attribute)
|
default(:create, attribute)
|
||||||
|
@ -599,11 +597,14 @@ defmodule Ash.Changeset do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_defaults(changeset, :update, keys) do
|
def set_defaults(changeset, :update, lazy?) do
|
||||||
changeset.resource
|
changeset.resource
|
||||||
|> Ash.Resource.Info.attributes()
|
|> Ash.Resource.Info.attributes()
|
||||||
|> Enum.filter(&(not is_nil(&1.update_default)))
|
|> 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 ->
|
|> Enum.reduce(changeset, fn attribute, changeset ->
|
||||||
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
force_change_new_attribute_lazy(changeset, attribute.name, fn ->
|
||||||
default(:update, attribute)
|
default(:update, attribute)
|
||||||
|
|
|
@ -217,11 +217,6 @@ defmodule Ash.Query do
|
||||||
tenant: [
|
tenant: [
|
||||||
type: :any,
|
type: :any,
|
||||||
doc: "set the tenant on the query"
|
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)
|
|> cast_params(action, args)
|
||||||
|> run_preparations(action, opts[:actor])
|
|> run_preparations(action, opts[:actor])
|
||||||
|> add_action_filters(action, opts[:actor])
|
|> add_action_filters(action, opts[:actor])
|
||||||
|> cast_arguments(action, opts[:defaults], true)
|
|> cast_arguments(action, true)
|
||||||
else
|
else
|
||||||
add_error(query, :action, "No such action #{action_name}")
|
add_error(query, :action, "No such action #{action_name}")
|
||||||
end
|
end
|
||||||
|
@ -801,23 +796,19 @@ defmodule Ash.Query do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
def cast_arguments(query, action, defaults \\ :all, only_supplied? \\ false) do
|
def cast_arguments(query, action, only_supplied? \\ false) do
|
||||||
action.arguments
|
action.arguments
|
||||||
|> Enum.reject(& &1.private?)
|
|> Enum.reject(& &1.private?)
|
||||||
|> Enum.reject(&(only_supplied? && match?({:ok, _}, fetch_argument(query, &1.name))))
|
|> Enum.reject(&(only_supplied? && match?({:ok, _}, fetch_argument(query, &1.name))))
|
||||||
|> Enum.reduce(query, fn argument, new_query ->
|
|> 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)
|
||||||
|
|
||||||
|
{ignore_nil_check, value} =
|
||||||
if argument_default(argument.default) do
|
if argument_default(argument.default) do
|
||||||
{true, value}
|
{true, value}
|
||||||
else
|
else
|
||||||
{false, value}
|
{false, value}
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
!ignore_nil_check && is_nil(value) && !argument.allow_nil? ->
|
!ignore_nil_check && is_nil(value) && !argument.allow_nil? ->
|
||||||
|
|
|
@ -82,12 +82,12 @@ defmodule Ash.Resource.Attribute do
|
||||||
update_default: [
|
update_default: [
|
||||||
type: {:custom, Ash.OptionsHelpers, :default, []},
|
type: {:custom, Ash.OptionsHelpers, :default, []},
|
||||||
doc:
|
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: [
|
default: [
|
||||||
type: {:custom, Ash.OptionsHelpers, :default, []},
|
type: {:custom, Ash.OptionsHelpers, :default, []},
|
||||||
doc:
|
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: [
|
description: [
|
||||||
type: :string,
|
type: :string,
|
||||||
|
@ -106,7 +106,10 @@ defmodule Ash.Resource.Attribute do
|
||||||
|> OptionsHelpers.set_default!(:writable?, false)
|
|> OptionsHelpers.set_default!(:writable?, false)
|
||||||
|> OptionsHelpers.set_default!(:private?, true)
|
|> OptionsHelpers.set_default!(:private?, true)
|
||||||
|> OptionsHelpers.set_default!(:default, &DateTime.utc_now/0)
|
|> 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!(:type, Ash.Type.UtcDatetimeUsec)
|
||||||
|> OptionsHelpers.set_default!(:allow_nil?, false)
|
|> OptionsHelpers.set_default!(:allow_nil?, false)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue