-
-
Notifications
You must be signed in to change notification settings - Fork 217
/
validate_manage_relationship_opts.ex
104 lines (92 loc) · 3.51 KB
/
validate_manage_relationship_opts.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
defmodule Ash.Resource.Verifiers.ValidateManagedRelationshipOpts do
@moduledoc """
Confirms that all action types declared on a resource are supported by its data layer
"""
use Spark.Dsl.Verifier
alias Ash.Changeset.ManagedRelationshipHelpers
alias Spark.Dsl.Verifier
require Logger
@impl true
def verify(dsl_state) do
relationships = Verifier.get_entities(dsl_state, [:relationships])
dsl_state
|> Verifier.get_entities([:actions])
|> Enum.reject(&(&1.type in [:read, :action]))
|> Enum.each(fn action ->
action.changes
|> Enum.filter(
&match?(%Ash.Resource.Change{change: {Ash.Resource.Change.ManageRelationship, _}}, &1)
)
|> Enum.each(fn %Ash.Resource.Change{change: {_, opts}} ->
unless Enum.find(action.arguments, &(&1.name == opts[:argument])) do
raise Spark.Error.DslError,
path:
[
:actions,
action.type,
action.name,
:change,
:manage_relationship
] ++ Enum.uniq([opts[:argument], opts[:relationship]]),
message: "Action #{action.name} has no argument `#{inspect(opts[:argument])}`."
end
relationship =
Enum.find(relationships, &(&1.name == opts[:relationship])) ||
raise Spark.Error.DslError,
path:
[
:actions,
action.type,
action.name,
:change,
:manage_relationship
] ++ Enum.uniq([opts[:argument], opts[:relationship]]),
message: "No such relationship #{opts[:relationship]} exists."
if ensure_compiled?(relationship) do
try do
manage_opts =
if opts[:opts][:type] do
defaults = Ash.Changeset.manage_relationship_opts(opts[:opts][:type])
Enum.reduce(defaults, Ash.Changeset.manage_relationship_schema(), fn {key, value},
manage_opts ->
Spark.Options.Helpers.set_default!(manage_opts, key, value)
end)
else
Ash.Changeset.manage_relationship_schema()
end
opts = Spark.Options.validate!(opts[:opts], manage_opts)
ManagedRelationshipHelpers.sanitize_opts(relationship, opts)
rescue
e ->
reraise Spark.Error.DslError,
[
path:
[
:actions,
action.type,
action.name,
:change,
:manage_relationship
] ++ Enum.uniq([opts[:argument], opts[:relationship]]),
message: """
The following error was raised when validating options provided to manage_relationship.
#{Exception.format(:error, e, __STACKTRACE__)}
"""
],
__STACKTRACE__
end
end
end)
end)
:ok
end
defp ensure_compiled?(%Ash.Resource.Relationships.ManyToMany{
through: through,
destination: destination
}) do
Code.ensure_loaded?(through) && Code.ensure_loaded?(destination)
end
defp ensure_compiled?(%{destination: destination}) do
Code.ensure_loaded?(destination)
end
end