Preloading multiple_select with existing selections

I’m using a multiple_select to allow a user to select multiple resource_types. It works perfecting when creating a “new” resource. But when I load an existing resource to “edit” it, the resource_types that were previously selected don’t show.

Here is the multiple select code I’m using based on what I found from previous posts in this forum:

<div>
  <%= label f, :resource_types %>
  <%= multiple_select f, :resource_types, Enum.map(@all_resource_types, &{&1.type, &1.id}),
      selected: Enum.map(@changeset.data.resource_types, &(&1.type)) %>
  <%= error_tag f, :resource_types %>
  </div>

I’m inspecting what is being passed in to make sure I’ve got values. The resource type is set correctly:

%SketchLinks.Resourceforms.Resourceform{
  __meta__: #Ecto.Schema.Metadata<:built, "resource_form">,
  begin_datetime: ~N[2016-01-01 00:00:00],
  delete_after_endtime: true,
  description: "Edit",
  end_datetime: ~N[2016-01-01 00:00:00],
  id: 16,
  image_url: "Edit",
  inserted_at: nil,
  is_event: true,
  is_free: true,
  is_private: true,
  publish_date: ~D[2016-01-01],
  resource_types: ["Book", "Blog"],
  resource_url: "Edit",
  title: "Edit2",
  updated_at: nil,
  usage_count: nil
}

And the changeset that gets passed into the template looks like this:

#Ecto.Changeset<action: nil, changes: %{}, errors: [],
 data: #SketchLinks.Resourceforms.Resourceform<>, valid?: true>

The error I get is this:

Called with 3 arguments
"Book"
:type
[]

Request: GET /resource_forms/16/edit
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        :erlang.apply("Book", :type, [])

So it is seeing the first string in the array, but then it chokes. The error says I’m passing 3 arguments, but I’m not. I’m only passing two arguments into Enum.map. What am I doing wrong?

and

These two pieces of code are not compatible - are the elements of resource_types supposed to be structs or binaries?

Also note: the values in selected should match values from the second element of the tuples passed to multiple_select, so in your example they should be ids not types.

Thank you for the help! Resource_types are formatted as a list of strings. I thought that by calling @changeset.data.resource_types it would just give me that array of strings. That’s what I thought I was passing into Enum.map.

Do I need to pass both a type and an id into selected? You mentioned just passing in an id, but the map I use to show all of the choices provides both an &1.type and &1.id. Do I need to match exactly what is given for the choices?