Found the solution (ref. Handling Upsert stale error)
- turn
on_conflict
into Ecto.Query - use
stale_error_field
to prevent upsert stale error
For example:
def upsert(%Post{} = post) do
on_conflict =
from Post,
where: [public: false],
update: [set: [title: "second"]]
post
|> Repo.insert(
conflict_target: [:id],
on_conflict: on_conflict,
stale_error_field: :public,
return: true
)
end