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
Edward Scott
Edward ScottOP•3y ago
and
# 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
I get a validation error: [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()
I can't spot the cause of the error. Any suggestion on how to proceed?
ZachDaniel
ZachDaniel•3y ago
🤔 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}
Edward Scott
Edward ScottOP•3y ago
I just want the variables to be owned by the 'compenent'. I will change to :map.
ZachDaniel
ZachDaniel•3y ago
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)
Edward Scott
Edward ScottOP•3y ago
That makes sense. Your suggestion worked. Thank you.

Did you find this page helpful?