Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The changeset does not define a constraint for a custom unique index #113

Closed
smt116 opened this issue Sep 29, 2022 · 2 comments
Closed

The changeset does not define a constraint for a custom unique index #113

smt116 opened this issue Sep 29, 2022 · 2 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@smt116
Copy link

smt116 commented Sep 29, 2022

Describe the bug

The following custom unique index:

postgres do
  # ...

  custom_indexes do
    index(["provider", "provider_id"], unique: true, where: "archived_at IS NULL and provider_id IS NOT NULL")
  end
end

Does not add a constraint on a changeset which results in the exception when inserting a duplicated record:

** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * table_provider_provider_id_index (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 defined the following constraints:

    * table_user_id_fkey (foreign_key_constraint)
    * table_pkey (unique_constraint)

    (ecto 3.8.4) lib/ecto/repo/schema.ex:783: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
    (elixir 1.14.0) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
    (ecto 3.8.4) lib/ecto/repo/schema.ex:768: Ecto.Repo.Schema.constraints_to_errors/3
    (ecto 3.8.4) lib/ecto/repo/schema.ex:749: Ecto.Repo.Schema.apply/4
    (ecto 3.8.4) lib/ecto/repo/schema.ex:367: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (ash_postgres 1.0.0-rc.5) lib/data_layer.ex:934: AshPostgres.DataLayer.create/2
    (ash 2.0.0-rc.7) lib/ash/actions/create.ex:378: anonymous fn/8 in Ash.Actions.Create.as_requests/5
    (ash 2.0.0-rc.7) lib/ash/changeset/changeset.ex:1463: Ash.Changeset.run_around_actions/2
    (ash 2.0.0-rc.7) lib/ash/actions/create.ex:313: anonymous fn/8 in Ash.Actions.Create.as_requests/5
    (ash 2.0.0-rc.7) lib/ash/engine/request.ex:1041: Ash.Engine.Request.do_try_resolve_local/4
    (ash 2.0.0-rc.7) lib/ash/engine/request.ex:281: Ash.Engine.Request.do_next/1
    (ash 2.0.0-rc.7) lib/ash/engine/request.ex:210: Ash.Engine.Request.next/1
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:610: Ash.Engine.advance_request/2
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:535: Ash.Engine.fully_advance_request/2
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:469: Ash.Engine.do_run_iteration/2
    (elixir 1.14.0) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:218: Ash.Engine.run_to_completion/1
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:167: Ash.Engine.do_run/2
    (ash 2.0.0-rc.7) lib/ash/engine/engine.ex:88: anonymous fn/2 in Ash.Engine.run/2
    (ecto_sql 3.8.3) lib/ecto/adapters/sql.ex:1222: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4

Expected behavior
All custom unique indexes should add a constraint to the changeset.

** Runtime

  • Elixir version 1.14.0
  • Erlang version 25.0.4
  • ash 2.0.0-rc.7
  • ash_admin 0.6.0-rc.1
  • ash_graphql 0.20.0-rc.1
  • ash_phoenix 1.0.0-rc.0
  • ash_postgres 1.0.0-rc.5
@smt116 smt116 added bug Something isn't working needs review labels Sep 29, 2022
@zachdaniel
Copy link
Contributor

🤔 yeah, this is interesting. There is a way to add custom unique indexes to be checked in the changeset. Specifically:

postgres do
  unique_index_names {[:provider, :provider_id], "...name of constraint"}
end

But we could likely derive these for custom constraints. The only thing is that we need to have atoms for the fields instead of strings, and we don't necessarily want to assume that every key provided to a custom index already exists as an atom.

So, to do this automatically we'd need to

  1. make custom_indexes take a list of atom for fields instead of strings
  2. add those to the list of unique constraint names to check for.

@zachdaniel zachdaniel added enhancement New feature or request good first issue Good for newcomers and removed bug Something isn't working needs review labels Sep 30, 2022
@zachdaniel
Copy link
Contributor

Fixed in: 0598376

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants