Multiple Select not working with associated data

I am trying to allow users to select multiple resource_types. They have a many-to-many relationship with a Resource. My relationships all work, but I can’t see them at all in my Liveview template. Here is the code I’m using in the template:

<%= inputs_for f, :resource_types, fn i -> %>
  <div class="form-group">
     <%= label i, :resource_types, "Select a resource type:" %>
     <%= multiple_select i, :resource_types, Enum.map(@all_resource_types, &{&1.type, &1.id}) %>
     <%= error_tag i, :resource_types %>
  </div>
  <% end %>

I can’t see ANYTHING in that inputs_for. Not even the label “Select a resource type:” shows up on my form.

In reading Jose Valim’s article on Working with Ecto Associations and Embeds, I realized that my problem may be that my “update” function was creating an empty Resource changeset without the associations set. Really quickly, here’s the basic resource-resource_type relationship:

schema "resources" do
    field :begin_datetime, :naive_datetime
    field :delete_after_endtime, :boolean, default: false
    field :description, :string
    field :end_datetime, :naive_datetime
    field :image_url, :string
    field :is_event, :boolean, default: false
    field :is_free, :boolean, default: false
    field :is_private, :boolean, default: false
    field :publish_date, :date
    field :resource_url, :string
    field :title, :string
    field :usage_count, :integer

    many_to_many :resource_types, Resourcetype, join_through: "join_resources_resourcetypes", on_delete: :delete_all

    timestamps()
  end

  @doc false
  def changeset(resource, attrs) do
    resource
    |> cast(attrs, [:title, :description, :image_url, :resource_url, :publish_date, :begin_datetime, :end_datetime, :is_event, :is_free, :is_private, :delete_after_endtime, :usage_count])
    |> validate_required([:title, :description, :resource_url, :is_free])
    |> unsafe_validate_unique(:resource_url, SketchLinks.Repo, message: "Resource with this url already exists.")
    |> unique_constraint(:resource_url)
    |> put_assoc(:resource_types, required: true)
  end

So I updated my “update” function to put_assoc an empty resource_type in hopes that the form would finally display the inputs_for section in the template … but I still have nothing.

Update function code:

def update(%{resource: resource} = assigns, socket) do
    changeset = Resources.change_resource(resource)
    changeset = Ecto.Changeset.put_assoc(changeset, :resource_types, [%Resourcetype{}])
    IO.puts "FormComponent UPDATE changeset"
    IO.inspect changeset
    IO.puts "Resource inside changeset"
    IO.inspect changeset.data
    # changeset = Resource.changeset(%Resource{resource_types: [%Resourcetype{}]})

    {:ok,
     socket
     |> assign(assigns)
     |> assign(changeset: changeset)
     |> assign(all_resource_types: Resourcetypes.list_resource_types())
    }
  end

The output from those debug inspects show that I do have an empty changeset and the data inside the changeset (the Resource) does not have any resource_types set. But that is despite me setting an empty Resourcetype.

FormComponent UPDATE changeset
#Ecto.Changeset<
  action: nil,
  changes: %{},
  errors: [
    resource_types: {"is invalid", [type: {:array, :map}]},
    title: {"can't be blank", [validation: :required]},
    description: {"can't be blank", [validation: :required]},
    resource_url: {"can't be blank", [validation: :required]}
  ],
  data: #MyApp.Resources.Resource<>,
  valid?: false
>
Resource inside changeset
%MyApp.Resources.Resource{
  __meta__: #Ecto.Schema.Metadata<:built, "resources">,
  begin_datetime: nil,
  delete_after_endtime: false,
  description: nil,
  end_datetime: nil,
  id: nil,
  image_url: nil,
  inserted_at: nil,
  is_event: false,
  is_free: false,
  is_private: false,
  publish_date: nil,
  resource_types: #Ecto.Association.NotLoaded<association :resource_types is not loaded>,
  resource_url: nil,
  title: nil,
  updated_at: nil,
  usage_count: nil
}

I don’t know what else to try to get the input_for to work. Without that, I can’t allow the user to select resource_types. I also need to figure out how to show “pre-selected” types when I’m in edit mode.

How do I get inputs_for to work so that 1) a user can see the form and select resource types while setting up a new resource AND 2) a user can see pre-selected resource_types when doing an edit?

UPDATE:
I managed to get the input_for form to show but as soon as I click on a resource_type, the form disappears. My inpsect debugging now shows this. I definitely see an empty Resource_type set. But it’s still not allowing me to select multiple items. The form just disappers as soon as I click on it

#Ecto.Changeset<
  action: nil,
  changes: %{
    resource_types: [
      #Ecto.Changeset<action: :insert, changes: %{}, errors: [],
       data: #MyApp.Resourcetypes.Resourcetype<>, valid?: true>
    ]
  },
  errors: [
    resource_types: {"is invalid", [type: {:array, :map}]},
    title: {"can't be blank", [validation: :required]},
    description: {"can't be blank", [validation: :required]},
    resource_url: {"can't be blank", [validation: :required]}
  ],
  data: #MyApp.Resources.Resource<>,
  valid?: false
>
Resource inside changeset
%SketchLinks.Resources.Resource{
  __meta__: #Ecto.Schema.Metadata<:built, "resources">,
  begin_datetime: nil,
  delete_after_endtime: false,
  description: nil,
  end_datetime: nil,
  id: nil,
  image_url: nil,
  inserted_at: nil,
  is_event: false,
  is_free: false,
  is_private: false,
  publish_date: nil,
  resource_types: #Ecto.Association.NotLoaded<association :resource_types is not loaded>,
  resource_url: nil,
  title: nil,
  updated_at: nil,
  usage_count: nil
}