DevLog.at

Learning Phoenix / Elixir

Lessons learned

Viewing Single Post (4/4)

Figuring out ecto's upsert behavior was a major pain. Take the following example:

%User{}
|> User.changeset(attrs)
|> Repo.insert!(
  on_conflict: :replace_all,
  conflict_target: :github_id
)

Here, :replace_all tells ecto to update the existing record in the db with your data from the changeset (when a conflict occurs).

This is great. However, the unexpected part is that :replace_all also includes the id column in its updates. In other words, when a conflict occurs, ecto updates the existing record with a new incremental id. What??

I don't know when you'd want this. But to stop it, you need to explicitly tell ecto to exclude id:

Repo.insert!(
  on_conflict: {:replace_all_except, [:id]},
  conflict_target: :steam_appid
)

11d

0 comments on this post

Sign in with GitHub to comment on this post.