wintermeyer
wintermeyer

Reputation: 8318

Select field with possible belongs_to values

I have Category and Product which belongs_to category. The setup:

mix phoenix.new shop
cd shop
mix ecto.create
mix phoenix.gen.html Category categories name
mix phoenix.gen.html Product products name category_id:integer
mix ecto.migrate

web/router.ex

[...]
scope "/", Shop do
  pipe_through :browser # Use the default browser stack

  get "/", PageController, :index
  resources "/categories", CategoryController
  resources "/products", ProductController
end
[...]

web/models/product.ex

defmodule Shop.Product do
  use Shop.Web, :model

  schema "products" do
    field :name, :string
    belongs_to :category, Vutuv.Category

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:name, :category_id])
    |> validate_required([:name, :category_id])
  end
end

The Problem

I'd like to render a drop down select field in the new form for products. So that a user can select a category for the product by name of the category. Currently the user can only enter the category_id:

web/templates/product/form.html.eex

[...]
<div class="form-group">
  <%= label f, :category_id, class: "control-label" %>
  <%= number_input f, :category_id, class: "form-control" %>
  <%= error_tag f, :category_id %>
</div>
[...]

What do I have to change do create a drop down select field which displays all the categories in the database by name?

Upvotes: 3

Views: 1421

Answers (1)

Dogbert
Dogbert

Reputation: 222348

I'd fetch the categories in a format that can be passed directly to Phoenix.HTML.Form.select/4 in the template:

...
categories = Repo.all(from(c in Category, select: {c.name, c.id}))
render "...", categories: categories

Then pass categories to Phoenix.HTML.Form.select/4 in the template:

<%= select f, :category_id, @categories %>

Upvotes: 4

Related Questions