list
table has a composite primary key of listing_profile
and listed_profile
.
I added unique_constraint
to changeset. But it doesn’t check uniqueness of the primary key.
# Should error
iex(8)> List.Entity.changeset(%List.Entity{listing_profile: 1, listed_profile: 2}, %{})
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
data: #Feder.Social.List.Entity<>, valid?: true>
On Postgres side, list_pkey
unique constraint works as expected.
# Existing key
iex> Repo.insert(%List.Entity{listing_profile: 1, listed_profile: 2})
** (Ecto.ConstraintError) constraint error when attempting to insert struct:
* list_pkey (unique_constraint)
...
What am I missing here?
# schema
@primary_key false
schema "list" do
field :listing_profile, :id, primary_key: true
field :listed_profile, :id, primary_key: true
end
def changeset(entity, attrs) do
entity
|> cast(attrs, [:listing_profile, :listed_profile])
|> validate_required([:listing_profile, :listed_profile])
|> unique_constraint([:listing_profile, :listed_profile], name: :list_pkey)
end
# migration
create table(:list, primary_key: false) do
add :listing_profile,
references(:profile, on_delete: :delete_all),
primary_key: true
add :listed_profile,
references(:profile, on_delete: :delete_all),
primary_key: true
end
Table "public.list"
Column | Type | Collation | Nullable | Default
-----------------+--------+-----------+----------+---------
listing_profile | bigint | | not null |
listed_profile | bigint | | not null |
Indexes:
"list_pkey" PRIMARY KEY, btree (listing_profile, listed_profile)
Foreign-key constraints:
"list_listed_profile_fkey" FOREIGN KEY (listed_profile) REFERENCES profile(id) ON DELETE CASCADE
"list_listing_profile_fkey" FOREIGN KEY (listing_profile) REFERENCES profile(id) ON DELETE CASCADE
Separating each field doesn’t help.
|> unique_constraint([:listing_profile, :listed_profile], name: :list_pkey)
# or
|> unique_constraint(:listing_profile, name: :list_pkey)
|> unique_constraint(:listed_profile, name: :list_pkey)