Ecto :map data Changeset on Phoenix form_for

Hi.

I created a Ecto schema with a :map field (Postgres jsonb).
My functions populate correctly but I can’t see them on Phoenix edit form. (although update works fine).

How can I correctly use :map field with changeset and Phoenix?

user.ex

defmodule Accounts.User do
  use Ecto.Schema
  import Ecto.Changeset
  alias __MODULE__

  schema "users" do
    field :email, :string
    field :enabled, :boolean, default: true, null: false
    field :password_hash, :string
    field :password, :string, virtual: true
    field :password_confirmation, :string, virtual: true
    field :data, :map

    timestamps()
  end
  ...
end

IIRC Phoenix will give an error if you don’t explicitly serialize the map with something like Poison

I figured out how to extract map field from changeset struct in Phoenix.
To make things easier I created a helper function.

common/phoenix_helper.ex

  def from_map(changeset_struct, map_field, field) do
    case changeset_struct.data.id do
      nil ->
        ""
      _ ->
        changeset_struct.data
        |> Map.get(map_field)
        |> Map.get(field)
    end
  end

web/web.ex

  def view do
    quote do
      ...
      import Common.PhoenixHelper
      alias Common.PhoenixHelper
    end
  end

form.html.eex

  <div class="form-group">
    <%= label f, :name, class: "control-label" %>
    <%= text_input f, :data_name, value: PhoenixHelper.from_map(f,:data,"name"), name: "user[data][name]", class: "form-control" %>
    <%= error_tag f, :name %>
  </div>
2 Likes