Ecto replace all except autogenerated fields

Hello guys, first post here.

Was wondering if this is an expected behaviour as i couldn’t find anything on the docs.

I have an schema like

 schema "foo" do
    field :name, :string
    field :uuid, Ecto.UUID, autogenerated: true
  end

When creating an upsert function:

  def upsert_foo(attrs \\ %{}) do
    %Foo{}
    |> Foo.changeset(attrs)
    |> Repo.insert(
      on_conflict: {:replace_all_except, [:id, :uuid]},
      conflict_target: [:uuid]
    )
  end

Now for some reason, the uuid every time i try to update a Foo object, his uuid is being replaced. How can this be avoided

1 Like

I believe the option name should be autogenerate, not autogenerated.

https://hexdocs.pm/ecto/Ecto.Schema.html#field/3-options

Try that and see if the issue is still there.

1 Like

It’s not being replaced. Try adding the returning: true option to Repo.insert. Without that it simply gives you back the struct that was attempted to be inserted. Which contains a new autogenerated uuid because it doesn’t know yet there will be a conflict.

6 Likes

Was an error writting the post, apologize for that. Issue is still happening

Solved by post from joey