Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't make work JSONB with Ecto model in Phoenix

I have been trying to save JSON in jsonb column in postgresql, I've tried this tutorial and also started reading Ecto API as well as Postgrex but can't make it work, a working example would enlight me :) so far I have added this to my config

config :bonsai, Bonsai.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "demo",
  password: "demo123",
  database: "bonsai_test",
  hostname: "localhost",
  pool: Ecto.Adapters.SQL.Sandbox,
  extensions: [{Postgrex.Extensions.JSON, [library: Poison]}]

This is my Model

defmodule Bonsai.Organization do
  use Bonsai.Web, :model

  schema "organizations" do
    field :name, :string
    field :currency, :string
    field :tenant, :string
    field :info, Bonsai.Json.Type, default: %{}
    field :settings, :map, default: %{} #, :map#, Bonsai.Json.Type

    timestamps
  end

  @required_fields ~w(name currency tenant)
  @optional_fields ~w()

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

And the definition of types is in web/utils/json.ex

defmodule Bonsai.Json.Type do
  @behaviour Ecto.Type
  alias Bonsai.Json

  def type, do: :json

  def load({:ok, json}), do: {:ok, json}
  def load(value), do: load(Poison.decode(value))

  def dump(value), do: Poison.encode(value)
end

When I try to test I can't get to save the info or settings map

defmodule Bonsai.OrganizationTest do
  use Bonsai.ModelCase

  alias Bonsai.Organization

  @valid_attrs %{currency: "USD", name: "Home", tenant: "bonsai",
    settings: %{"last_save" => true},
    info: %{"address" => "Samaipata", "mobile" => "73732677", "age" => 40}
  }
  test "Store json data" do
    changeset = Organization.changeset(%Organization{}, @valid_attrs)
    {:ok, org} = Bonsai.Repo.insert(changeset)
    assert @valid_attrs.info() == org.info
  end
end
like image 778
Boris Barroso Avatar asked Mar 15 '16 00:03

Boris Barroso


1 Answers

I´m not rly sure why its not working for you, but:

make sure you have the newest postgresql version, json support kinda new.

This is working for me, maybe it helps.

  • migration file

    def change do
    create table(:objects) do
     add :drawing, :jsonb
     timestamps
    end
    
  • I use a json field as well, but in my model its a map:

     use .Web, :model
      schema "objects" do
       field :drawing, :map
       timestamps
      end
    
like image 163
murphy1312 Avatar answered Oct 24 '22 10:10

murphy1312