Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions lib/verifiers/validate_references.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,29 @@ defmodule AshPostgres.Verifiers.ValidateReferences do
dsl
|> AshPostgres.DataLayer.Info.references()
|> Enum.each(fn reference ->
if !Ash.Resource.Info.relationship(dsl, reference.relationship) do
raise Spark.Error.DslError,
path: [:postgres, :references, reference.relationship],
module: Verifier.get_persisted(dsl, :module),
message:
"Found reference configuration for relationship `#{reference.relationship}`, but no such relationship exists",
location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :references])
relationship = Ash.Resource.Info.relationship(dsl, reference.relationship)

cond do
is_nil(relationship) ->
raise Spark.Error.DslError,
path: [:postgres, :references, reference.relationship],
module: Verifier.get_persisted(dsl, :module),
message:
"Found reference configuration for relationship `#{reference.relationship}`, but no such relationship exists",
location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :references])

relationship.type != :belongs_to ->
raise Spark.Error.DslError,
path: [:postgres, :references, reference.relationship],
module: Verifier.get_persisted(dsl, :module),
message:
"Found reference configuration for relationship `#{reference.relationship}`, but it is a `#{relationship.type}` relationship. " <>
"References can only be configured for `belongs_to` relationships, because the foreign key is defined on the table with the `belongs_to` relationship. " <>
"To configure the behavior of this foreign key, add the reference configuration to the resource with the corresponding `belongs_to` relationship.",
location: Spark.Dsl.Transformer.get_section_anno(dsl, [:postgres, :references])

true ->
:ok
end
end)

Expand Down
62 changes: 62 additions & 0 deletions test/references_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,68 @@ defmodule AshPostgres.ReferencesTest do
assert io =~ "Unsupported match_type"
end

test "raises error when reference is configured for a has_many relationship" do
Code.compiler_options(ignore_module_conflict: true)
on_exit(fn -> Code.compiler_options(ignore_module_conflict: false) end)

{_, io} =
with_io(:stderr, fn ->
defmodule Parent do
@moduledoc false
use Ash.Resource,
domain: nil,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key(:id)
end

relationships do
has_many :children, AshPostgres.ReferencesTest.Child
end

postgres do
table("parents")
repo(AshPostgres.TestRepo)

references do
reference :children, on_delete: :delete
end
end

actions do
defaults([:create, :read, :update, :destroy])
end
end

defmodule Child do
@moduledoc false
use Ash.Resource,
domain: nil,
data_layer: AshPostgres.DataLayer

attributes do
uuid_primary_key(:id)
end

relationships do
belongs_to :parent, AshPostgres.ReferencesTest.Parent
end

postgres do
table("children")
repo(AshPostgres.TestRepo)
end

actions do
defaults([:create, :read, :update, :destroy])
end
end
end)

assert io =~ "References can only be configured for `belongs_to` relationships"
end

test "named reference results in properly applied foreign_key_constraint/3 on the underlying changeset" do
# Create a comment with an invalid post_id
assert {:error, %Ash.Error.Invalid{errors: errors}} =
Expand Down
Loading