Having trouble with generating form with :has_many field

schema "categories" do
    field :name, :string
    field :description, :string

    has_many :sub_categories, MyApp.Category.SubCategory

    timestamps(type: :utc_datetime)
  end

  @doc false
  def changeset(%MyApp.Category{} = category, attrs) do
    category
    |> cast(attrs, [:name, :description])
    |> cast_assoc(:sub_categories)
    |> validate_required([:name, :description])
    |> validate_length(:name, min: 3, max: 50)
    |> validate_length(:description, min: 5, max: 200)
  end

schema "sub_categories" do
    field :name, :string

    belongs_to :category, MyApp.Category
  end

  @doc false
  def changeset(%MyApp.Category.SubCategory{} = sub_category, attrs) do
    sub_category
    |> cast(attrs, [:name, :category_id])
  end

I have these schema and want to generate nested association field in my form component in LiveView

In live_component

  def update(%{category: category} = assigns, socket) do
    changeset = Categories.change_category(category, %{})

    {:ok,
     socket
     |> assign(assigns)
     |> assign(:changeset, changeset)
     |> assign(:can_save, changeset.valid?)}
  end

in render function

          <%= inputs_for f, :sub_categories, fn sc -> %>
             <div class="sm:grid sm:grid-cols-5 sm:gap-4 sm:items-start sm:pt-5 sm:pb-5">
              <%= label sc, :name, class: "block text-center text-sm font-medium text-gray-700 sm:mt-px sm:pt-2" %>
               <div class="mt-1 sm:mt-0 sm:col-span-2">
                <%= text_input sc, :name,
                 [phx_debounce: "500",
                  required: true,
                  class: "mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md"] %>
              <%= error_tag sc, :name %>
               </div>
             </div>
           <% end %>

But inputs_for function draws nothing in the page
What am I missing?

A :default, :append or :prepend.

End of the section, just above the CSRF protection topic.

1 Like

How can I add :append or :prepend to inputs_for?

1 Like

Is there anything in your :sub_categories collection? If it is empty you will not see anything rendered, so you must set a default value or prepend/append the list of subcategories that you want.

<%= inputs_for f, :sub_categories, [default: %SubCategory{}], fn sc -> %>
<%= inputs_for f, :sub_categories, [prepend: [%SubCategory{}, %SubCategory{}]], fn sc -> %>
<%= inputs_for f, :sub_categories, [append: [%SubCategory{}, %SubCategory{}]], fn sc -> %>

Docs for Phoenix.HTML.Form.inputs_for/4 and the available options: Phoenix.HTML.Form — Phoenix.HTML v3.2.0

2 Likes