How to create options_for_select tag from Repo.all

I would like to make select box with options_for_select.
I made data from Repo.all. However it has meta data header.

How can I put in options_for_select to make select box.

What have you tried? Aren’t the official docs enough?

I am also having the same issue.

    versions = Repo.list_versions()
    render(conn, :home, layout: false, versions: versions)
  <.input 
    name="version"
    type="select" 
    value="1"
    options={@versions}
  />

** (exit) an exception was raised:
** (Protocol.UndefinedError) protocol Enumerable not implemented for %Cbuilder.Cbuilder.Repo.Version{meta: ecto.Schema.Metadata<:loaded, “versions”>, id: 1, name: “Version-8.6.2
│”,

Naively I’d say this looks very straightforward: does Repo.list_versions always return a list?

It returns the contents of the table which I assume is a list?

protocol Enumerable not implemented for %Cbuilder.Cbuilder.Repo.Version{__meta__: #Ecto.Schema.Metadata<:loaded, "versions">, id: 1, name: "Version-8.6.2", inserted_at: ~N[2023-10-01 07:42:30], updated_at: ~N[2023-10-01 07:42:30]} of type Cbuilder.Cbuilder.Repo.Version (a struct)

does this mean the objects coming back from the table to do not constitute a list?

Seems like it.

You can replace this line of code:

versions = Repo.list_versions()

…with:

versions = Repo.list_versions() |> IO.inspect(limit: :infinity)

And check your console.

You’re sending a list of structs, you need a list of tuples representing the name and value of each <option>, eg.:

Repo.list_versions |> Enum.map(&({&1.name, &1.id}))
1 Like

Under the hood, the default .input core component uses Phoenix.HTML.Form.options_for_select/2 that @dimitarvp linked above to process the options. That function expects the options assign to be a list of tuples ["Display Value": "tag value", "Admin": "admin", "User": "user"].

You could do something like this to transform what Ecto returns into what options_for_select/2 and .input expects.

options = for version <- Repo.list_versions, do: {verson.name, verson.id}

1 Like

That is perfect thank you!