egor

egor

Union Forms and NoSuchInput Error

I’m building an application with a plugin system where each component can have different configuration parameters based on the plugin type selected.

I’ve implemented the Union Forms approach from the documentation for my plugin parameters, but I’m encountering an issue.

My Setup

I have a resource (Plugin) with a params attribute that uses a union type to accommodate different plugin parameter structures:

defmodule MyApp.Plugins.Plugin do
  use Ash.Resource, otp_app: :my_app, domain: MyApp.Plugins, data_layer: AshPostgres.DataLayer

  # Other configuration...

  attributes do
    integer_primary_key :id
    attribute :name, :string
    attribute :active, :boolean, default: false
    attribute :plugin_type, :module
    # This is the union attribute that holds different parameter configurations
    attribute :params, :plugin_params
    # Other attributes...
  end

  # Actions, relationships, etc.
end

The union type for plugin parameters:

defmodule MyApp.Types.PluginParams do
  defmodule TypeAParams do
    use Ash.Resource, data_layer: :embedded

    attributes do
      attribute :window_size, :integer, default: 3000
      attribute :threshold, :float, default: 0.70
      # Other parameters...
    end

    actions do
      defaults [:read, :destroy, create: :*, update: :*]
    end
  end

  use Ash.Type.NewType,
    subtype_of: :union,
    constraints: [
      types: [
        type_a: [
          type: TypeAParams,
          tag: :type,
          tag_value: :type_a
        ]
        # Other plugin types...
      ]
    ]
end

In my form component:

<.inputs_for :let={fc} field={@form[:params]}>
  <.input
    field={fc[:_union_type]}
    phx-change="type-changed"
    type="select"
    label="Plugin Type"
    options={["Type A": "type_a"]}
  />

  <%= case fc.params["_union_type"] do %>
    <% "type_a" -> %>
      <.input type="number" label="Window Size" field={fc[:window_size]} />
      <% # Other type_a inputs... %>
  <% end %>
</.inputs_for>

The Issue

When rendering the form, the current values are correctly displayed in the inputs. However, when I try to change any input in the nested form, I get this error:

%Ash.Error.Invalid.NoSuchInput{
  calculation: nil,
  resource: MyApp.Types.PluginParams.TypeAParams,
  action: :update,
  input: "window_size",
  inputs: MapSet.new([]),
  did_you_mean: [],
  # Other error details...
}

I’m following the type-changed handler from the documentation:

def handle_event("type-changed", %{"_target" => path} = params, socket) do
  new_type = get_in(params, path)
  path = :lists.droplast(path)

  form =
    socket.assigns.form
    |> AshPhoenix.Form.remove_form(path)
    |> AshPhoenix.Form.add_form(path, params: %{"_union_type" => new_type})

  {:noreply, assign(socket, :form, form)}
end

Any insights on what I might be doing wrong? The form renders correctly with the initial values but fails when trying to update any field.

Marked As Solved

egor

egor

I figured out the issue. Turns out the bug wasn’t in Ash itself, but in the docs! The examples for union forms were missing public? true on the embedded resource attributes, which caused the updates to fail. I’m gonna submit a PR (#324) to fix that.

To reproduce the problem I’ve created a repo minibikini/ash_phoenix_union_form_example which now has a working example of a union form in Ash, perhaps someone will find it useful.

Where Next?

Popular in Questions Top

vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Other popular topics Top

baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

We're in Beta

About us Mission Statement