Upsert conditional update e.g update only when existing data is outdated

Found the solution (ref. Handling Upsert stale error)

  1. turn on_conflict into Ecto.Query
  2. 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

5 Likes