How to insert array of maps in Ecto

I have a model with field of type array defined:

defmodule QsiSearchService.Features.FeatureProperties do
  use Ecto.Schema
  import Ecto.Changeset
  alias QsiSearchService.Features.{FeatureProperties, FeatureType}

  @primary_key {:id, :binary_id, autogenerate: true}
  @foreign_key_type :binary_id
  schema "feature_properties" do
    field :fields, {:array, :map}
    belongs_to :feature_type, FeatureType

    timestamps()
  end

  @doc false
  def changeset(%FeatureProperties{} = feature_properties, attrs) do
    feature_properties
    |> cast(attrs, [:fields, :feature_type_id])
    |> validate_required([:fields, :feature_type_id])
  end
end

When I try creating a record:

@feature_properties_attrs %{fields: [
    %{"name" => "PROGRESS_STATUS", "type" => "string"},
    %{"name" => "VOLTAGE", "type" => "number"}
  ]}

{:ok, feature_properties} = 
      @feature_properties_attrs
      |> Map.put(:feature_type_id, created_feature_type.id)
      |> Features.create_feature_properties()

I get the following error:

 ** (ArgumentError) Postgrex expected a binary, got %{"name" => "PROGRESS_STATUS", "type" => "string"}. Please make sure the value you are passing matches the definition in
 your table or in your query or convert the value accordingly.

Is this kind of operation possible, or do I have to create this schema using embeds?

Thanks

1 Like

What is the type of the column in DB? Try setting :json or :jsonb in migration and it should work.

1 Like

Hey @wojtekmach thanks for the answer. This is my migration its an array of jsonb

defmodule QsiSearchService.Repo.Migrations.CreateFeatureProperties do
  use Ecto.Migration

  def change do
    create table(:feature_properties, primary_key: false) do
      add :id, :binary_id, primary_key: true
      add :fields, {:array, :jsonb}
      add :feature_type_id, references(:feature_types, on_delete: :nothing, type: :binary_id)

      timestamps()
    end

    create index(:feature_properties, [:feature_type_id])
  end
end

Should I change it to just jsonb type?

hey @callmeahab try with empty array,
add :fields, :jsonb, default: "[]"