How do I use the Postgres JSONB / Postgrex JSON extension?

Hi all,

I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.

I’m trying to use Postgres’ JSONB via the :map datatype.

Here’s my migration to add it to my table:

defmodule MyApp.Repo.Migrations.AddMapFieldToUser do
  use Ecto.Migration

  def change do
    alter table(:users) do
      add :data, :map
    end
  end
end

Here’s my schema:

defmodule MyApp.User do
  use MyApp.Web, :model
  use Coherence.Schema

  schema "users" do
    field :first_name, :string
    field :last_name, :string
    field :email, :string
    field :data, :map

    coherence_schema()

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:first_name, :last_name, :email] ++ coherence_fields)
    |> unique_constraint(:email)
    |> validate_required([:first_name, :last_name, :email])
    |> validate_coherence(params)
  end
end

I’ve been trying to set values into the data map using a changeset, but I haven’t had any luck. I’ve tried using both a JSON string and a map.

JSON string:

changeset = User.changeset(retrieved_user, %{data: "{test:'awesome'}"})
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
 data: #MyApp.User<>, valid?: true>

Map:

changeset = User.changeset(john, %{data: %{test: "awesome"}})
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
 data: #PodioBackup.User<>, valid?: true>

You’ll see that the changes map is empty.

Which leads me to believe that I am clearly missing something! :sweat_smile: And I’m thinking maybe I need to add this JSON extension that many websites are referring to: postgrex/lib/postgrex/extensions/json.ex at master · elixir-ecto/postgrex · GitHub

How do I actually use that JSON extension? And, what am I doing wrong?

Thanks for the help in advance! :slight_smile: