Using AshPhoenix.Form to update embedded resource

I am unsure if this is the best way to present my issue. I have an embedded resource that I am trying to update via the AshPhoenix.Form.

  • Domain = Accounts
  • Resource = Organization
  • Embedded Resource = Config

get an organization resource

organization = Community.Accounts.get_organization_by_domain_slug!(“testinc-com”)

create an organization form

organization_form = Community.Accounts.form_to_update_organization(organization)

create an organization embedded “config” form

config_form_update = Community.Accounts.form_to_update_organization_config(organization)

favicon is the property to be updated

params = %{favicon: “https://www.testinc.com/images/favicon.ico”}

validate the form with the update and submit

submitted_config_form_update = config_form_update
|> AshPhoenix.Form.validate(params)
|> AshPhoenix.Form.submit!(params: params)

the ‘config’ favicon is updated correctly in the embedded ‘config’

iex(54)> submitted_config_form_update
%Community.Accounts.Config{
logo: “https://www.testinc.com/images/logo.svg”,
favicon: “https://www.testinc.com/images/favicon.ico”,
status: :setup,
supported_languages: [“en”],
supported_email_domains: [“testinc.com”],
meta: ###Ecto.Schema.Metadata<:built, “”>
}

update config in the organization resource

output = AshPhoenix.Form.submit!(organization_form, params: %{config: submitted_config_form_update})

unhappy face here

the favicon is not updated

iex(55)> output
%Community.Accounts.Organization{
id: “622032a8-8d7c-48ce-acf7-c946685e2a2f”,
name: “Test Inc.”,
url: “https://www.testinc.com”,
domain: “testinc.com”,
domain_slug: “testinc-com”,
status: :signed_up,
config: %Community.Accounts.Config{
logo: “https://www.testinc.com/images/logo.svg”,
favicon: nil,
status: :setup,
supported_languages: [“en”],
supported_email_domains: [“testinc.com”],
meta: #Ecto.Schema.Metadata<:built, “”>
},
organization_config_hash: “4b79239bf82e36870f0d2b640f911dcdbd7b7942ff2eb641c625c9642a99877e”,
inserted_at: ~U[2025-07-24 14:16:19.714496Z],
updated_at: ~U[2025-07-24 20:54:22.441046Z],
meta: #Ecto.Schema.Metadata<:loaded, “organizations”>
}

Found it! It isn’t calling the update action I thought it was and the one it is calling didn’t have “:config” in the accept.

Also you can skip the validate call if the next call is submit. Submit will automatically call validate.

Thanks good to know!!

New question on this topic. Is there a way to tell the AshPhoenix.Form.submit function to call a specific action? I see there is an “:action_opts” but I have not found an example of how to use it or more specifically what it does.

You choose the action when you create the form, i.e AshPhoenix.Form.for_create(...) or when using a form code interface.

That is what I thought should be happening but the call to “Accounts.form_to_update_organization_config(organization)” gives me a Form/Changeset for the embedded resource, which I thought was correct to allow validation of the embedded subform.

# get an organization resource
organization = Community.Accounts.get_organization_by_domain_slug!("testinc-com")
# get config_update form
config_update_form = Community.Accounts.form_to_update_organization_config(organization)
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

domain code

  resources do
    resource Community.Accounts.Organization do
      define :create_organization, action: :create_organization
      define :update_organization, action: :update_organization
      define :read_organizations, action: :read
      define :get_organization_by_domain_slug, action: :read, get_by: :domain_slug
      define :get_organization_by_id, action: :read, get_by: :id
      define :destroy_organization, action: :destroy_organization

      # embedded config schema
      define :update_organization_config, action: :update_organization_config
    end

resource code

defmodule Community.Accounts.Organization do
...
  actions do
    ...
    update :update_organization do
      accept [:name, :url, :config]         # i had to add :config here to make it work 
      require_atomic? false
    end

    update :update_organization_config do   # i thought this would be called
      accept [:config]
      require_atomic? false
    end

    destroy :destroy_organization do
    end
  end
  ...

:thinking: I’m not sure I understand what you’re looking to do unfortunately. form_to_update_organization_config would be giving you a form for this action: :update_organization_config on :organization. Are you looking to customize the action used on the embedded resource? Might need to see a more complete example to help.