Search code examples
postgresqlelixirphoenix-frameworkecto

How to perform atom update in embedded schema model with `jsonb_set`?


How to update only one key in map, I would like to perform it by jsonb_set like here: stackoverflow example or in transaction to avoid potential conflicts in database, is it possible with Ecto?

defmodule MySuperApp.Profile do
  use MySuperApp.Model
  schema "profiles" do
    field :name, :string
    embeds_one :settigns, MySuperApp.Settigns
  end
  def changeset(struct, params) do
    struct
    |> change
    |> put_embed(:settigns, MySuerApp.Settigns.changeset(model, params))
  end
end
defmodule MySuperApp.Settigns do
  use MySuperApp.Model

  @settigns %{socket: true, page: true, android: false, ios: false}

  embedded_schema do
    field :follow, :boolean

    field :action, :map, default: @settigns
  end

  def changeset(struct, _params) do
    # I would like to update only web key and leave old keys
    model |> change(action: %{web: false}) # this will override old map -> changes: %{action: %{web: false}
  end
end

Solution

  • No. Ecto currently does not support partial updates of the embeds with the high-level API (like changesets).

    You could achieve this by using raw SQL queries through Ecto.Adapters.SQL.query/4 or in more recent versions Repo.query/3.