Skip to content

If a change fails a constraint with composite key only the first key name is reported in the errors #4651

@ponychicken

Description

@ponychicken

Elixir version

Elixir 1.18.4 (compiled with Erlang/OTP 27)

Database and Version

--

Ecto Versions

ecto 3.13.2

Database Adapter and Versions (postgrex, myxql, etc)

--

Current behavior

If you have a table with a composite pkey:


  def change do
    create table(:widgets, primary_key: false) do
      add :key1, :integer, primary_key: true
      add :key2, :integer, primary_key: true
      add :name, :string
    end
  end

and then set it in the changeset def


  @primary_key false
  schema "widgets" do
    field :key1, :integer, primary_key: true
    field :key2, :integer, primary_key: true
    field :name, :string
  end

  def changeset(widget, attrs) do
    widget
    |> cast(attrs, [:key1, :key2, :name])
    |> unique_constraint([:key1, :key2], name: :widgets_pkey)
  end

Then when a changeset fails the constraint you will receive a message like:
#Ecto.Changeset<action: :insert, changes: %{name: "XXCCXX", key1: 1, key2: 2}, errors: [key1: {"has already been taken", [constraint: :unique, constraint_name: "widgets_pkey"]}], data: ....<>, valid?: false, ...>

Expected behavior

I dont know if you want to treat this as a bug, i found it confusing and it made me check the db if the constraint was set-up correctly. I thing either putting both keys as into the errors would be more clear.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions