How to determine the cause of a form validation error
I have a couple of resources:
defmodule XrtConfiguratorApp.Template.Component do
# Using Ash.Resource turns this module into an Ash resource.
use Ash.Resource,
# Tells Ash you want this resource to store its data in Postgres.
data_layer: AshPostgres.DataLayer
# The Postgres keyword is specific to the AshPostgres module.
postgres do
...
end
# Defines convenience methods for
# interacting with the resource programmatically.
code_interface do
define_for XrtConfiguratorApp.Template
define :create, action: :create
define :read_all, action: :read
define :update, action: :update
define :destroy, action: :destroy
define :get_by_id, args: [:id], action: :by_id
end
actions do
# Exposes default built in actions to manage the resource
defaults [:create, :read, :destroy]
update :update do
argument :variables, {:array, :uuid}
change manage_relationship(:variables, type: :direct_control)
end
# Defines custom read action which fetches post by id.
read :by_id do
...
end
# Attributes are simple pieces of data that exist in your resource
attributes do
# Add an autogenerated UUID primary key called `:id`.
uuid_primary_key :id
# Add a string type attribute called `:name`
attribute :name, :string do
# We don't want the name to ever be `nil`
allow_nil? false
end
attribute :description, :string
# Add a string type attribute called `:content`
# If allow_nil? is not specified, then content can be nil
attribute :content, :string do
allow_nil? false
end
attribute :optional, :boolean do
allow_nil? false
end
attribute :device_service, :boolean do
allow_nil? false
end
end
identities do
identity :name, [:name]
end
relationships do
has_many :variables, XrtConfiguratorApp.Template.Variable
end
end
defmodule XrtConfiguratorApp.Template.Component do
# Using Ash.Resource turns this module into an Ash resource.
use Ash.Resource,
# Tells Ash you want this resource to store its data in Postgres.
data_layer: AshPostgres.DataLayer
# The Postgres keyword is specific to the AshPostgres module.
postgres do
...
end
# Defines convenience methods for
# interacting with the resource programmatically.
code_interface do
define_for XrtConfiguratorApp.Template
define :create, action: :create
define :read_all, action: :read
define :update, action: :update
define :destroy, action: :destroy
define :get_by_id, args: [:id], action: :by_id
end
actions do
# Exposes default built in actions to manage the resource
defaults [:create, :read, :destroy]
update :update do
argument :variables, {:array, :uuid}
change manage_relationship(:variables, type: :direct_control)
end
# Defines custom read action which fetches post by id.
read :by_id do
...
end
# Attributes are simple pieces of data that exist in your resource
attributes do
# Add an autogenerated UUID primary key called `:id`.
uuid_primary_key :id
# Add a string type attribute called `:name`
attribute :name, :string do
# We don't want the name to ever be `nil`
allow_nil? false
end
attribute :description, :string
# Add a string type attribute called `:content`
# If allow_nil? is not specified, then content can be nil
attribute :content, :string do
allow_nil? false
end
attribute :optional, :boolean do
allow_nil? false
end
attribute :device_service, :boolean do
allow_nil? false
end
end
identities do
identity :name, [:name]
end
relationships do
has_many :variables, XrtConfiguratorApp.Template.Variable
end
end
5 Replies
and
I get a validation error:
I can't spot the cause of the error. Any suggestion on how to proceed?
# interacting with the resource programmatically.
code_interface do
define_for XrtConfiguratorApp.Template
define :create, action: :create
define :read_all, action: :read
define :update, action: :update
define :destroy, action: :destroy
define :get_by_id, args: [:id], action: :by_id
end
actions do
# Exposes default built in actions to manage the resource
defaults [:create, :read, :update, :destroy]
# Defines custom read action which fetches post by id.
read :by_id do
# This action has one argument :id of type :uuid
argument :id, :uuid, allow_nil?: false
# Tells us we expect this action to return a single result
get? true
# Filters the `:id` given in the argument
# against the `id` of each element in the resource
filter expr(id == ^arg(:id))
end
end
# Attributes are simple pieces of data that exist in your resource
attributes do
# Add an autogenerated UUID primary key called `:id`.
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :description, :string do
allow_nil? false
end
attribute :default_value, :string
end
relationships do
belongs_to :component, XrtConfiguratorApp.Template.Component do
attribute_writable? true
end
end
end
# interacting with the resource programmatically.
code_interface do
define_for XrtConfiguratorApp.Template
define :create, action: :create
define :read_all, action: :read
define :update, action: :update
define :destroy, action: :destroy
define :get_by_id, args: [:id], action: :by_id
end
actions do
# Exposes default built in actions to manage the resource
defaults [:create, :read, :update, :destroy]
# Defines custom read action which fetches post by id.
read :by_id do
# This action has one argument :id of type :uuid
argument :id, :uuid, allow_nil?: false
# Tells us we expect this action to return a single result
get? true
# Filters the `:id` given in the argument
# against the `id` of each element in the resource
filter expr(id == ^arg(:id))
end
end
# Attributes are simple pieces of data that exist in your resource
attributes do
# Add an autogenerated UUID primary key called `:id`.
uuid_primary_key :id
attribute :name, :string do
allow_nil? false
end
attribute :description, :string do
allow_nil? false
end
attribute :default_value, :string
end
relationships do
belongs_to :component, XrtConfiguratorApp.Template.Component do
attribute_writable? true
end
end
end
[field: :variables, message: \"at index 1 is invalid\", index: 1]
from the validate in my update handler calling AshPhoenix.Form.submit(AshPhoenix.Form.validate(socket.assigns.update_form, form))
The form is defined using:
form = comp |> AshPhoenix.Form.for_update(:update,
api: XrtConfiguratorApp.Template,
forms: [
variables: [
resource: Variable,
data: comp.variables,
update_action: :update,
type: :list
]]) |> to_form()
form = comp |> AshPhoenix.Form.for_update(:update,
api: XrtConfiguratorApp.Template,
forms: [
variables: [
resource: Variable,
data: comp.variables,
update_action: :update,
type: :list
]]) |> to_form()
🤔 something does seem strange there.
I suspect the issue is here:
argument :variables, {:array, :uuid}
Do you mean to be providing a list of uuids? Or do you want {:array, :map}
I just want the variables to be owned by the 'compenent'. I will change to :map.
The reason the error was non descriptive is likely because it was expecting a string and got a map, so the "entire value" was invalid
(i.e not some specific field of it)
That makes sense. Your suggestion worked. Thank you.