diff --git a/lib/ash_phoenix/form_data/changeset.ex b/lib/ash_phoenix/form_data/changeset.ex index 80c23d3..346e43c 100644 --- a/lib/ash_phoenix/form_data/changeset.ex +++ b/lib/ash_phoenix/form_data/changeset.ex @@ -87,7 +87,6 @@ defimpl Phoenix.HTML.FormData, for: Ash.Changeset do {prepend, opts} = Keyword.pop(opts, :prepend, []) {append, opts} = Keyword.pop(opts, :append, []) {use_data?, opts} = Keyword.pop(opts, :use_data?, false) - changeset_opts = [skip_defaults: :all] id = to_string(id || form.id <> "_#{field}") name = to_string(name || form.name <> "[#{field}]") @@ -150,7 +149,7 @@ defimpl Phoenix.HTML.FormData, for: Ash.Changeset do end data - |> to_nested_form(changeset, source, resource, id, name, opts, changeset_opts) + |> to_nested_form(changeset, source, resource, id, name, opts) |> List.wrap() end diff --git a/lib/ash_phoenix/form_data/helpers.ex b/lib/ash_phoenix/form_data/helpers.ex index 0ab70a1..17e6cd3 100644 --- a/lib/ash_phoenix/form_data/helpers.ex +++ b/lib/ash_phoenix/form_data/helpers.ex @@ -96,8 +96,7 @@ defmodule AshPhoenix.FormData.Helpers do resource, id, name, - opts, - changeset_opts + opts ) when is_list(data) do changesets = @@ -107,7 +106,7 @@ defmodule AshPhoenix.FormData.Helpers do update_action = Ash.Resource.Info.primary_action(resource, :update) if update_action do - Ash.Changeset.for_update(data, update_action.name, %{}, changeset_opts) + Ash.Changeset.for_update(data, update_action.name, %{}) else Ash.Changeset.new(data) end @@ -115,7 +114,7 @@ defmodule AshPhoenix.FormData.Helpers do create_action = Ash.Resource.Info.primary_action(resource, :create) if create_action do - Ash.Changeset.for_create(resource, create_action.name, data, changeset_opts) + Ash.Changeset.for_create(resource, create_action.name, data) else Ash.Changeset.new(resource, data) end @@ -149,7 +148,7 @@ defmodule AshPhoenix.FormData.Helpers do name: name <> "[" <> index_string <> "]", index: index, errors: form_for_errors(changeset, opts), - data: data, + data: changeset.data, params: changeset.params, hidden: hidden, options: opts @@ -164,8 +163,7 @@ defmodule AshPhoenix.FormData.Helpers do resource, id, name, - opts, - changeset_opts + opts ) do create_action = Ash.Resource.Info.primary_action(resource, :create) @@ -175,9 +173,11 @@ defmodule AshPhoenix.FormData.Helpers do cond do is_struct(data) -> if update_action do - Ash.Changeset.for_update(data, update_action.name, %{}, changeset_opts) + Ash.Changeset.for_update(data, update_action.name, %{}) else - Ash.Changeset.new(data) + resource + |> Ash.Changeset.new(data) + |> Map.put(:params, data) end is_nil(data) -> @@ -185,9 +185,11 @@ defmodule AshPhoenix.FormData.Helpers do true -> if create_action do - Ash.Changeset.for_create(resource, create_action.name, data, changeset_opts) + Ash.Changeset.for_create(resource, create_action.name, data) else - Ash.Changeset.new(resource, data) + resource + |> Ash.Changeset.new(data) + |> Map.put(:params, data) end end @@ -230,8 +232,7 @@ defmodule AshPhoenix.FormData.Helpers do resource, id, name, - opts, - changeset_opts + opts ) when is_list(data) do create_action = @@ -246,9 +247,9 @@ defmodule AshPhoenix.FormData.Helpers do data |> Enum.map(fn data -> if is_struct(data) do - Ash.Changeset.for_update(data, update_action, %{}, changeset_opts) + Ash.Changeset.for_update(data, update_action, %{}) else - Ash.Changeset.for_create(resource, create_action, data, changeset_opts) + Ash.Changeset.for_create(resource, create_action, data) end end) @@ -279,7 +280,7 @@ defmodule AshPhoenix.FormData.Helpers do name: name <> "[" <> index_string <> "]", index: index, errors: form_for_errors(changeset, opts), - data: data, + data: changeset.data, params: changeset.params, hidden: hidden, options: opts @@ -294,8 +295,7 @@ defmodule AshPhoenix.FormData.Helpers do resource, id, name, - opts, - changeset_opts + opts ) do create_action = attribute.constraints[:create_action] || @@ -308,13 +308,13 @@ defmodule AshPhoenix.FormData.Helpers do changeset = cond do is_struct(data) -> - Ash.Changeset.for_update(data, update_action, %{}, changeset_opts) + Ash.Changeset.for_update(data, update_action, %{}) is_nil(data) -> nil true -> - Ash.Changeset.for_create(resource, create_action, data, changeset_opts) + Ash.Changeset.for_create(resource, create_action, data) end if changeset do diff --git a/lib/ash_phoenix/form_data/query.ex b/lib/ash_phoenix/form_data/query.ex index bd4349d..1718e33 100644 --- a/lib/ash_phoenix/form_data/query.ex +++ b/lib/ash_phoenix/form_data/query.ex @@ -31,18 +31,17 @@ defimpl Phoenix.HTML.FormData, for: Ash.Query do end @impl true - def to_form(changeset, form, field, opts) do + def to_form(query, form, field, opts) do {name, opts} = Keyword.pop(opts, :as) {id, opts} = Keyword.pop(opts, :id) {prepend, opts} = Keyword.pop(opts, :prepend, []) {append, opts} = Keyword.pop(opts, :append, []) - changeset_opts = [skip_defaults: :all] id = to_string(id || form.id <> "_#{field}") name = to_string(name || form.name <> "[#{field}]") arguments = - if changeset.action do - changeset.action.arguments + if query.action do + query.action.arguments else [] end @@ -60,7 +59,7 @@ defimpl Phoenix.HTML.FormData, for: Ash.Query do raise "Cannot use `form_for` with an argument unless the type is an embedded resource" resource -> - data = Ash.Changeset.get_argument(changeset, arg.name) + data = Ash.Query.get_argument(query, arg.name) data = case arg.type do @@ -90,13 +89,12 @@ defimpl Phoenix.HTML.FormData, for: Ash.Query do data |> to_nested_form( - changeset, + query, source, resource, id, name, - opts, - changeset_opts + opts ) |> List.wrap() end diff --git a/lib/ash_phoenix/form_data/relationship_input.ex b/lib/ash_phoenix/form_data/relationship_input.ex deleted file mode 100644 index fe3ff0d..0000000 --- a/lib/ash_phoenix/form_data/relationship_input.ex +++ /dev/null @@ -1,349 +0,0 @@ -# defmodule AshPhoenix.FormData.RelationshipInput do -# defstruct [:resource, :action] - -# defimpl Phoenix.HTML.FormData do -# import AshPhoenix.FormData.Helpers - -# @impl true -# def input_type(%{resource: resource, action: action}, _, field) do -# attribute = Ash.Resource.Info.attribute(resource, field) - -# if attribute do -# type_to_form_type(attribute.type) -# else -# argument = get_argument(action, field) - -# if argument do -# type_to_form_type(argument.type) -# else -# :text_input -# end -# end -# end - -# @impl true -# def input_value(input, form, field) do -# case get_changing_value(input, field) do -# {:ok, value} -> -# value - -# :error -> -# case Map.fetch(input.data, field) do -# {:ok, value} -> -# value - -# _ -> -# Ash.Changeset.get_argument(changeset, field) -# end -# end -# end - -# defp get_changing_value(changeset, field) do -# with :error <- Map.fetch(changeset.attributes, field), -# :error <- Map.fetch(changeset.params, field) do -# Map.fetch(changeset.params, to_string(field)) -# end -# end - -# @impl true -# def to_form(changeset, opts) do -# {name, opts} = Keyword.pop(opts, :as) - -# name = to_string(name || form_for_name(changeset.resource)) -# id = Keyword.get(opts, :id) || name - -# hidden = -# if changeset.action_type == :update do -# changeset.data -# |> Map.take(Ash.Resource.Info.primary_key(changeset.resource)) -# |> Enum.to_list() -# else -# [] -# end - -# %Phoenix.HTML.Form{ -# action: changeset.action && changeset.action.name, -# source: Ash.Changeset.put_context(changeset, :form, %{path: []}), -# impl: __MODULE__, -# id: id, -# name: name, -# errors: form_for_errors(changeset, opts), -# data: changeset.data, -# params: changeset.params, -# hidden: hidden, -# options: Keyword.put_new(opts, :method, form_for_method(changeset)) -# } -# end - -# @impl true -# def to_form(changeset, form, field, opts) do -# {name, opts} = Keyword.pop(opts, :as) -# {id, opts} = Keyword.pop(opts, :id) -# {prepend, opts} = Keyword.pop(opts, :prepend, []) -# {append, opts} = Keyword.pop(opts, :append, []) -# changeset_opts = [skip_defaults: :all] -# id = to_string(id || form.id <> "_#{field}") -# name = to_string(name || form.name <> "[#{field}]") - -# arguments = -# if changeset.action do -# changeset.action.arguments -# else -# [] -# end - -# {source, resource, data, opts} = -# cond do -# attr = Ash.Resource.Info.attribute(changeset.resource, field) -> -# case get_embedded(attr.type) do -# nil -> -# raise "Cannot use `form_for` with an attribute unless the type is an embedded resource" - -# resource -> -# data = Ash.Changeset.get_attribute(changeset, attr.name) - -# data = -# case attr.type do -# {:array, _} -> -# List.wrap(data) - -# _ -> -# data -# end - -# {attr, resource, data, opts} -# end - -# arg = -# Enum.find( -# arguments, -# &(&1.name == field || to_string(&1.name) == field) -# ) -> -# case get_embedded(arg.type) do -# nil -> -# raise "Cannot use `form_for` with an argument unless the type is an embedded resource" - -# resource -> -# data = Ash.Changeset.get_argument(changeset, arg.name) - -# data = -# case arg.type do -# {:array, _} -> -# List.wrap(data) - -# _ -> -# data -# end - -# {arg, resource, data} -# end - -# true -> -# raise "Cannot use `form_for` with anything except embedded resources in attributes/arguments" -# end - -# data = -# if is_list(data) do -# prepend ++ data ++ append -# else -# data -# end - -# data -# |> to_nested_form(changeset, source, resource, id, name, opts, changeset_opts) -# |> List.wrap() -# end - -# defp to_nested_form( -# data, -# original_changeset, -# attribute, -# resource, -# id, -# name, -# opts, -# changeset_opts -# ) -# when is_list(data) do -# create_action = -# attribute.constraints[:create_action] || -# Ash.Resource.Info.primary_action!(resource, :create).name - -# update_action = -# attribute.constraints[:update_action] || -# Ash.Resource.Info.primary_action!(resource, :update).name - -# changesets = -# data -# |> Enum.map(fn data -> -# if is_struct(data) do -# Ash.Changeset.for_update(data, update_action, %{}, changeset_opts) -# else -# Ash.Changeset.for_create(resource, create_action, data, changeset_opts) -# end -# end) - -# changesets = -# if AshPhoenix.hiding_errors?(original_changeset) do -# Enum.map(changesets, &AshPhoenix.hide_errors/1) -# else -# changesets -# end - -# for {changeset, index} <- Enum.with_index(changesets) do -# index_string = Integer.to_string(index) - -# hidden = -# if changeset.action_type == :update do -# changeset.data -# |> Map.take(Ash.Resource.Info.primary_key(changeset.resource)) -# |> Enum.to_list() -# else -# [] -# end - -# %Phoenix.HTML.Form{ -# action: changeset.action && changeset.action.name, -# source: changeset, -# impl: __MODULE__, -# id: id <> "_" <> index_string, -# name: name <> "[" <> index_string <> "]", -# index: index, -# errors: form_for_errors(changeset, opts), -# data: data, -# params: changeset.params, -# hidden: hidden, -# options: opts -# } -# end -# end - -# defp to_nested_form( -# data, -# original_changeset, -# attribute, -# resource, -# id, -# name, -# opts, -# changeset_opts -# ) do -# create_action = -# attribute.constraints[:create_action] || -# Ash.Resource.Info.primary_action!(resource, :create).name - -# update_action = -# attribute.constraints[:update_action] || -# Ash.Resource.Info.primary_action!(resource, :update).name - -# changeset = -# cond do -# is_struct(data) -> -# Ash.Changeset.for_update(data, update_action, %{}, changeset_opts) - -# is_nil(data) -> -# nil - -# true -> -# Ash.Changeset.for_create(resource, create_action, data, changeset_opts) -# end - -# if changeset do -# changeset = -# if AshPhoenix.hiding_errors?(original_changeset) do -# AshPhoenix.hide_errors(changeset) -# else -# changeset -# end - -# hidden = -# if changeset.action_type == :update do -# changeset.data -# |> Map.take(Ash.Resource.Info.primary_key(changeset.resource)) -# |> Enum.to_list() -# else -# [] -# end - -# %Phoenix.HTML.Form{ -# action: changeset.action && changeset.action.name, -# source: changeset, -# impl: __MODULE__, -# id: id, -# name: name, -# errors: form_for_errors(changeset, opts), -# data: data, -# params: changeset.params, -# hidden: hidden, -# options: opts -# } -# end -# end - -# defp get_embedded({:array, type}), do: get_embedded(type) - -# defp get_embedded(type) when is_atom(type) do -# if Ash.Resource.Info.embedded?(type) do -# type -# end -# end - -# defp get_embedded(_), do: nil - -# @impl true -# def input_validations(changeset, _, field) do -# attribute_or_argument = -# Ash.Resource.Info.attribute(changeset.resource, field) || -# get_argument(changeset.action, field) - -# if attribute_or_argument do -# [required: !attribute_or_argument.allow_nil?] ++ type_validations(attribute_or_argument) -# else -# [] -# end -# end - -# defp type_validations(%{type: Ash.Types.Integer, constraints: constraints}) do -# constraints -# |> Kernel.||([]) -# |> Keyword.take([:max, :min]) -# |> Keyword.put(:step, 1) -# end - -# defp type_validations(%{type: Ash.Types.Decimal, constraints: constraints}) do -# constraints -# |> Kernel.||([]) -# |> Keyword.take([:max, :min]) -# |> Keyword.put(:step, "any") -# end - -# defp type_validations(%{type: Ash.Types.String, constraints: constraints}) do -# if constraints[:trim?] do -# # We should consider using the `match` validation here, but we can't -# # add a title here, so we can't set an error message -# # min_length = to_string(constraints[:min_length]) -# # max_length = to_string(constraints[:max_length]) -# # [match: "(\S\s*){#{min_length},#{max_length}}"] -# [] -# else -# validations = -# if constraints[:min_length] do -# [min_length: constraints[:min_length]] -# else -# [] -# end - -# if constraints[:min_length] do -# Keyword.put(constraints, :min_length, constraints[:min_length]) -# else -# validations -# end -# end -# end - -# defp type_validations(_), do: [] - -# defp form_for_method(%{action_type: :create}), do: "post" -# defp form_for_method(_), do: "put" -# end -# end