fix: primary keys are implicitly uniquely constrained.

Closes #332.
This commit is contained in:
James Harton 2023-06-15 12:25:46 +12:00
parent 7b46e131f9
commit 424085b825
Signed by: james
GPG key ID: 90E82DAA13F624F4

View file

@ -60,28 +60,41 @@ defmodule AshAuthentication.Validations.Attribute do
""" """
@spec validate_attribute_unique_constraint(map, [atom], module) :: :ok | {:error, Exception.t()} @spec validate_attribute_unique_constraint(map, [atom], module) :: :ok | {:error, Exception.t()}
def validate_attribute_unique_constraint(dsl_state, fields, resource) do def validate_attribute_unique_constraint(dsl_state, fields, resource) do
message =
case fields do
[field] ->
"The `#{inspect(field)}` attribute on the resource `#{inspect(resource)}` should be uniquely constrained"
[_ | _] = fields ->
fields =
fields
|> Enum.map(&"`#{&1}`")
|> to_sentence(final: "and")
"The #{fields} attributes on the resource `#{inspect(resource)}` should be uniquely constrained"
end
fields = MapSet.new(fields) fields = MapSet.new(fields)
dsl_state identities =
|> Info.identities() dsl_state
|> Enum.find(&MapSet.equal?(MapSet.new(&1.keys), fields)) |> Info.identities()
|> Enum.map(&MapSet.new(&1.keys))
primary_key =
dsl_state
|> Info.primary_key()
|> MapSet.new()
identities
|> Enum.concat(primary_key)
|> Enum.find(&MapSet.equal?(&1, fields))
|> case do |> case do
nil -> {:error, DslError.exception(path: [:identities, :identity], message: message)} nil ->
_ -> :ok message =
case Enum.to_list(fields) do
[field] ->
"The `#{inspect(field)}` attribute on the resource `#{inspect(resource)}` should be uniquely constrained"
[_ | _] = fields ->
fields =
fields
|> Enum.map(&"`#{&1}`")
|> to_sentence(final: "and")
"The #{fields} attributes on the resource `#{inspect(resource)}` should be uniquely constrained"
end
{:error, DslError.exception(path: [:identities, :identity], message: message)}
_ ->
:ok
end end
end end
end end