Constraint error when attempting to insert struct(unique_constraint)

Hello,

I read the other posts about this error, but so far nothing helps. So… I get the following error:

error] GenServer #PID<0.847.0> terminating
** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * player_tour_pkey (unique_constraint)

If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `unique_constraint/3` on your changeset with the constraint
`:name` as an option.

The changeset has not defined any constraint.

and so on, with this function in my context:

  def bump_player_points(%Tour{} = tour, player_id, points) do
    tt = tour.id
    query = from(pt in PlayerTour, where: pt.tour_id == ^tt and pt.player_id == ^player_id, preload: [:tour, :player])
    assoc = Repo.one(query)

    assoc
    |> PlayerTour.changeset(%{points: points})
    |> Repo.insert()
  end

The PlayerTour model:

  schema "player_tour" do

    belongs_to :tour, Tour
    belongs_to :player, Player

    timestamps()
  end

  @doc false

  def changeset(struct, attrs \\ %{}) do
    struct
    |> cast(attrs, [:tour_id, :player_id])
    |> validate_required([:tour_id, :player_id])
  end

And its migration:

  def change do
    create table(:player_tour) do
      add(:player_id, references(:players, on_delete: :delete_all))
      add(:tour_id, references(:tours, on_delete: :delete_all))
      add(:points, :decimal)
      timestamps()
    end

    create unique_index(:player_tour, [:player_id, :tour_id], name: :player_tour_unique_index)

  end

I have tried to drop the unique_index and create a new one,

    create unique_index(:player_tour, [:player_id, :tour_id, :points], name: :player_tour_unique_index)

But the error still stands… Why?

On a quick glance it looks like you are actually attempting to insert a PlayerTour object with a primary key ID that already exists. Doesn’t seem like your unique index on both other fields has anything to do with your problem.

2 Likes

What if you try Repo.update/2 instead of Repo.insert?

Your changeset should have a unique_constraint to help that error propagate up to forms