From 0d56f4ef45ca6b25fc041d8292fbee085f4061ea Mon Sep 17 00:00:00 2001 From: T Floyd Wright Date: Thu, 15 Oct 2026 10:41:18 -0800 Subject: [PATCH] fix: keep newly added singular embeds across form changes A singular embed added with the "+" button disappeared on the next form change when none of its fields rendered a named input, e.g. an embed with only array fields and no values yet. The change params then had no key for the embed, so cast_embed fell back to the record's nil value. Stop skipping the hidden fields inputs_for renders. The _persistent_id keeps a singular embed's key in the params, and embeds with a primary key now send their id, so cast_embed updates existing entries instead of replacing them. skip_hidden only existed to keep these fields from conflicting with the old empty-string removal input, which the drop param has since replaced. --- lib/live_admin/components.ex | 2 +- test/live_admin/components/container_test.exs | 22 +++++++++++++++++++ test/support/resources.ex | 10 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/live_admin/components.ex b/lib/live_admin/components.ex index b0d16f7..b20db96 100644 --- a/lib/live_admin/components.ex +++ b/lib/live_admin/components.ex @@ -88,7 +88,7 @@ defmodule LiveAdmin.Components do

{@field |> humanize() |> trans()}

<%= if @value do %> - <.inputs_for :let={embed_form} field={@form[@field]} skip_hidden={true}> + <.inputs_for :let={embed_form} field={@form[@field]}> <%= if sortable?(@value) do %>
{trans("Move here")}
<% end %> diff --git a/test/live_admin/components/container_test.exs b/test/live_admin/components/container_test.exs index dd0acb2..d723193 100644 --- a/test/live_admin/components/container_test.exs +++ b/test/live_admin/components/container_test.exs @@ -262,6 +262,28 @@ defmodule LiveAdmin.Components.ContainerTest do end end + describe "edit resource after adding singular embed with only array fields" do + setup %{conn: conn} do + user = Repo.insert!(%User{}) + + {:ok, view, _} = live(conn, "/user/edit/#{user.id}") + + view + |> element("form") + |> render_change(%{"params" => %{"private_data_sort" => "0"}}) + + view + |> element("form") + |> render_change(%{"params" => %{"name" => "test"}}) + + %{view: view} + end + + test "keeps embed form field", %{view: view} do + assert has_element?(view, "#params_private_data_0_aliases_array_input") + end + end + describe "edit resource with plural embed with multiple entries" do setup %{conn: conn} do post = Repo.insert!(%Post{title: "test", previous_versions: [%Version{}, %Version{}]}) diff --git a/test/support/resources.ex b/test/support/resources.ex index 2d90dde..d68f459 100644 --- a/test/support/resources.ex +++ b/test/support/resources.ex @@ -37,6 +37,7 @@ defmodule LiveAdminTest.User do field(:encrypted_password, :string) embeds_one(:settings, LiveAdminTest.Settings) + embeds_one(:private_data, LiveAdminTest.PrivateData) end def user_task(_, _), do: {:ok, "worked"} @@ -96,6 +97,15 @@ defmodule LiveAdminTest.Settings do end end +defmodule LiveAdminTest.PrivateData do + use Ecto.Schema + + @primary_key false + embedded_schema do + field(:aliases, {:array, :string}) + end +end + defmodule LiveAdminTest.Post.Version do use Ecto.Schema