Skip to content

Commit 64e3a56

Browse files
committed
chore: Ash.Subject delegates to sub-modules
1 parent 77a3fc1 commit 64e3a56

File tree

4 files changed

+72
-141
lines changed

4 files changed

+72
-141
lines changed

lib/ash/action_input.ex

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ defmodule Ash.ActionInput do
463463
- `set_argument/3` for setting argument values
464464
- `for_action/4` for providing initial arguments
465465
"""
466-
@spec fetch_argument(t, atom | String.t()) :: {:ok, term()} | :error
466+
@spec fetch_argument(t, atom | binary) :: {:ok, term()} | :error
467467
def fetch_argument(input, argument) when is_atom(argument) or is_binary(argument) do
468468
with :error <- Map.fetch(input.arguments, argument) do
469469
Map.fetch(input.arguments, to_string(argument))
@@ -507,7 +507,7 @@ defmodule Ash.ActionInput do
507507
- `set_private_argument/3` for setting private arguments
508508
- `for_action/4` for providing initial arguments
509509
"""
510-
@spec set_argument(input :: t(), name :: atom, value :: term()) :: t()
510+
@spec set_argument(input :: t(), name :: atom | binary, value :: term()) :: t()
511511
def set_argument(input, argument, value) do
512512
if input.action do
513513
argument =
@@ -553,6 +553,22 @@ defmodule Ash.ActionInput do
553553
end
554554
end
555555

556+
@doc """
557+
Deletes one or more arguments from the subject.
558+
559+
## Parameters
560+
561+
* `subject` - The subject to delete arguments from
562+
* `arguments` - Single argument name or list of argument names to delete
563+
"""
564+
def delete_argument(input, argument_or_arguments) do
565+
argument_or_arguments
566+
|> List.wrap()
567+
|> Enum.reduce(input, fn argument, input ->
568+
%{input | arguments: Map.delete(input.arguments, argument)}
569+
end)
570+
end
571+
556572
@doc """
557573
Sets a private argument value on the action input.
558574

lib/ash/query/query.ex

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,9 +2796,12 @@ defmodule Ash.Query do
27962796
- `set_argument/3` for adding arguments to queries
27972797
- `for_read/4` for creating queries with arguments
27982798
"""
2799-
@spec get_argument(t, atom) :: term
2800-
def get_argument(query, argument) when is_atom(argument) do
2801-
Map.get(query.arguments, argument) || Map.get(query.arguments, to_string(argument))
2799+
@spec get_argument(t, atom | binary) :: term
2800+
def get_argument(query, argument) when is_atom(argument) or is_binary(argument) do
2801+
case fetch_argument(query, argument) do
2802+
{:ok, value} -> value
2803+
:error -> nil
2804+
end
28022805
end
28032806

28042807
@doc """
@@ -2831,8 +2834,8 @@ defmodule Ash.Query do
28312834
- `set_argument/3` for adding arguments to queries
28322835
- `for_read/4` for creating queries with arguments
28332836
"""
2834-
@spec fetch_argument(t, atom) :: {:ok, term} | :error
2835-
def fetch_argument(query, argument) when is_atom(argument) do
2837+
@spec fetch_argument(t, atom | binary) :: {:ok, term} | :error
2838+
def fetch_argument(query, argument) when is_atom(argument) or is_binary(argument) do
28362839
case Map.fetch(query.arguments, argument) do
28372840
{:ok, value} ->
28382841
{:ok, value}

lib/ash/subject.ex

Lines changed: 35 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,8 @@ defmodule Ash.Subject do
121121
Ash.Query.set_context(subject, map)
122122
end
123123

124-
def set_context(subject, nil), do: subject
125-
126-
def set_context(subject, map) do
127-
%{
128-
subject
129-
| context:
130-
subject.context
131-
|> Ash.Helpers.deep_merge_maps(map)
132-
|> then(&Ash.Helpers.deep_merge_maps(&1, map[:shared] || %{}))
133-
}
124+
def set_context(%Ash.ActionInput{} = subject, map) do
125+
Ash.ActionInput.set_context(subject, map)
134126
end
135127

136128
@doc """
@@ -174,32 +166,24 @@ defmodule Ash.Subject do
174166
@spec get_argument(subject :: t(), argument :: atom() | binary(), default :: term()) :: term()
175167
def get_argument(subject, argument, default \\ nil)
176168

177-
def get_argument(subject, argument, default) when is_atom(argument) do
178-
value =
179-
if Map.has_key?(subject.arguments, argument) do
180-
Map.get(subject.arguments, argument)
181-
else
182-
Map.get(subject.arguments, to_string(argument))
183-
end
184-
185-
if is_nil(value) do
186-
default
187-
else
188-
value
169+
def get_argument(%Ash.Changeset{} = subject, argument, default) do
170+
case Ash.Changeset.get_argument(subject, argument) do
171+
nil -> default
172+
value -> value
189173
end
190174
end
191175

192-
def get_argument(subject, argument, default) when is_binary(argument) do
193-
subject.arguments
194-
|> Enum.find(fn {key, _} ->
195-
to_string(key) == argument
196-
end)
197-
|> case do
198-
{_key, value} ->
199-
value
176+
def get_argument(%Ash.Query{} = subject, argument, default) do
177+
case Ash.Query.get_argument(subject, argument) do
178+
nil -> default
179+
value -> value
180+
end
181+
end
200182

201-
_ ->
202-
default
183+
def get_argument(%Ash.ActionInput{} = subject, argument, default) do
184+
case Ash.ActionInput.get_argument(subject, argument) do
185+
nil -> default
186+
value -> value
203187
end
204188
end
205189

@@ -224,31 +208,16 @@ defmodule Ash.Subject do
224208
* `argument` - The argument name (atom or string)
225209
"""
226210
@spec fetch_argument(subject :: t(), argument :: atom() | binary()) :: {:ok, term()} | :error
227-
def fetch_argument(subject, argument) when is_atom(argument) do
228-
case Map.fetch(subject.arguments, argument) do
229-
{:ok, value} ->
230-
{:ok, value}
231-
232-
:error ->
233-
case Map.fetch(subject.arguments, to_string(argument)) do
234-
{:ok, value} -> {:ok, value}
235-
:error -> :error
236-
end
237-
end
211+
def fetch_argument(%Ash.Changeset{} = subject, argument) do
212+
Ash.Changeset.fetch_argument(subject, argument)
238213
end
239214

240-
def fetch_argument(subject, argument) when is_binary(argument) do
241-
subject.arguments
242-
|> Enum.find(fn {key, _} ->
243-
to_string(key) == argument
244-
end)
245-
|> case do
246-
{_key, value} ->
247-
{:ok, value}
215+
def fetch_argument(%Ash.Query{} = subject, argument) do
216+
Ash.Query.fetch_argument(subject, argument)
217+
end
248218

249-
_ ->
250-
:error
251-
end
219+
def fetch_argument(%Ash.ActionInput{} = subject, argument) do
220+
Ash.ActionInput.fetch_argument(subject, argument)
252221
end
253222

254223
@doc """
@@ -310,12 +279,8 @@ defmodule Ash.Subject do
310279
Ash.Query.delete_argument(subject, argument_or_arguments)
311280
end
312281

313-
def delete_argument(subject, argument_or_arguments) do
314-
argument_or_arguments
315-
|> List.wrap()
316-
|> Enum.reduce(subject, fn argument, subject ->
317-
%{subject | arguments: Map.delete(subject.arguments, argument)}
318-
end)
282+
def delete_argument(%Ash.ActionInput{} = subject, argument_or_arguments) do
283+
Ash.ActionInput.delete_argument(subject, argument_or_arguments)
319284
end
320285

321286
@doc """
@@ -390,12 +355,8 @@ defmodule Ash.Subject do
390355
Ash.Query.before_action(subject, callback, opts)
391356
end
392357

393-
def before_action(subject, callback, opts) do
394-
if opts[:prepend?] do
395-
%{subject | before_action: [callback | subject.before_action]}
396-
else
397-
%{subject | before_action: subject.before_action ++ [callback]}
398-
end
358+
def before_action(%Ash.ActionInput{} = subject, callback, opts) do
359+
Ash.ActionInput.before_action(subject, callback, opts)
399360
end
400361

401362
@doc """
@@ -424,12 +385,8 @@ defmodule Ash.Subject do
424385
Ash.Query.after_action(subject, callback)
425386
end
426387

427-
def after_action(subject, callback, opts) do
428-
if opts[:prepend?] do
429-
%{subject | after_action: [callback | subject.after_action]}
430-
else
431-
%{subject | after_action: subject.after_action ++ [callback]}
432-
end
388+
def after_action(%Ash.ActionInput{} = subject, callback, opts) do
389+
Ash.ActionInput.after_action(subject, callback, opts)
433390
end
434391

435392
@doc """
@@ -490,12 +447,8 @@ defmodule Ash.Subject do
490447
Ash.Query.before_transaction(subject, callback, opts)
491448
end
492449

493-
def before_transaction(subject, callback, opts) do
494-
if opts[:prepend?] do
495-
%{subject | before_transaction: [callback | subject.before_transaction]}
496-
else
497-
%{subject | before_transaction: subject.before_transaction ++ [callback]}
498-
end
450+
def before_transaction(%Ash.ActionInput{} = subject, callback, opts) do
451+
Ash.ActionInput.before_transaction(subject, callback, opts)
499452
end
500453

501454
@doc """
@@ -566,12 +519,8 @@ defmodule Ash.Subject do
566519
Ash.Query.after_transaction(subject, callback, opts)
567520
end
568521

569-
def after_transaction(subject, callback, opts) do
570-
if opts[:prepend?] do
571-
%{subject | after_transaction: [callback | subject.after_transaction]}
572-
else
573-
%{subject | after_transaction: subject.after_transaction ++ [callback]}
574-
end
522+
def after_transaction(%Ash.ActionInput{} = subject, callback, opts) do
523+
Ash.ActionInput.after_transaction(subject, callback, opts)
575524
end
576525

577526
@doc """
@@ -652,11 +601,7 @@ defmodule Ash.Subject do
652601
Ash.Query.around_transaction(subject, callback, opts)
653602
end
654603

655-
def around_transaction(subject, callback, opts) do
656-
if opts[:prepend?] do
657-
%{subject | around_transaction: [callback | subject.around_transaction]}
658-
else
659-
%{subject | around_transaction: subject.around_transaction ++ [callback]}
660-
end
604+
def around_transaction(%Ash.ActionInput{} = subject, callback, opts) do
605+
Ash.ActionInput.around_transaction(subject, callback, opts)
661606
end
662607
end

test/subject_test.exs

Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,9 @@ defmodule Ash.SubjectTest do
181181
subject = new_subject(subject_type)
182182

183183
# Set an argument that works for all types
184-
result =
185-
case subject_type do
186-
Ash.ActionInput -> Ash.Subject.set_argument(subject, :name, "value")
187-
_ -> Ash.Subject.set_argument(subject, :custom_arg, "value")
188-
end
184+
result = %{subject | arguments: %{age: 42}}
189185

190-
expected_arg = if subject_type == Ash.ActionInput, do: :name, else: :custom_arg
191-
assert Ash.Subject.get_argument(result, expected_arg) == "value"
192-
assert Ash.Subject.get_argument(result, :non_existent) == nil
186+
assert Ash.Subject.get_argument(result, :age) == 42
193187
assert is_struct(result, subject_type)
194188
end
195189
end
@@ -199,15 +193,9 @@ defmodule Ash.SubjectTest do
199193
subject = new_subject(subject_type)
200194

201195
# Set an argument that works for all types
202-
result =
203-
case subject_type do
204-
Ash.ActionInput -> Ash.Subject.set_argument(subject, :name, "value")
205-
_ -> Ash.Subject.set_argument(subject, :test_arg, "value")
206-
end
196+
result = %{subject | arguments: %{"age" => 42}}
207197

208-
# Should find argument by string key even though it was set with atom
209-
expected_arg_str = if subject_type == Ash.ActionInput, do: "name", else: "test_arg"
210-
assert Ash.Subject.get_argument(result, expected_arg_str) == "value"
198+
assert Ash.Subject.get_argument(result, "age") == 42
211199
assert is_struct(result, subject_type)
212200
end
213201
end
@@ -218,7 +206,6 @@ defmodule Ash.SubjectTest do
218206

219207
assert Ash.Subject.get_argument(subject, :missing_arg, "default_value") == "default_value"
220208
assert Ash.Subject.get_argument(subject, "missing_arg", :default_atom) == :default_atom
221-
assert Ash.Subject.get_argument(subject, :missing_arg, 42) == 42
222209
assert is_struct(subject, subject_type)
223210
end
224211
end
@@ -228,20 +215,9 @@ defmodule Ash.SubjectTest do
228215
subject = new_subject(subject_type)
229216

230217
# Set an argument that works for all types
231-
result =
232-
case subject_type do
233-
Ash.ActionInput -> Ash.Subject.set_argument(subject, :name, "actual_value")
234-
_ -> Ash.Subject.set_argument(subject, :existing_arg, "actual_value")
235-
end
236-
237-
expected_arg = if subject_type == Ash.ActionInput, do: :name, else: :existing_arg
238-
expected_arg_str = if subject_type == Ash.ActionInput, do: "name", else: "existing_arg"
239-
240-
assert Ash.Subject.get_argument(result, expected_arg, "default_value") == "actual_value"
241-
242-
assert Ash.Subject.get_argument(result, expected_arg_str, "default_value") ==
243-
"actual_value"
218+
result = %{subject | arguments: %{name: "actual_value"}}
244219

220+
assert Ash.Subject.get_argument(result, :name, "default_value") == "actual_value"
245221
assert is_struct(result, subject_type)
246222
end
247223
end
@@ -253,14 +229,10 @@ defmodule Ash.SubjectTest do
253229
subject = new_subject(subject_type)
254230

255231
# Set an argument that works for all types
256-
result =
257-
case subject_type do
258-
Ash.ActionInput -> Ash.Subject.set_argument(subject, :name, "value")
259-
_ -> Ash.Subject.set_argument(subject, :custom_arg, "value")
260-
end
232+
result = %{subject | arguments: %{"age" => 42, name: "value"}}
261233

262-
expected_arg = if subject_type == Ash.ActionInput, do: :name, else: :custom_arg
263-
assert {:ok, "value"} = Ash.Subject.fetch_argument(result, expected_arg)
234+
assert {:ok, "value"} = Ash.Subject.fetch_argument(result, :name)
235+
assert {:ok, 42} = Ash.Subject.fetch_argument(result, "age")
264236
assert :error = Ash.Subject.fetch_argument(result, :missing)
265237
assert is_struct(result, subject_type)
266238
end
@@ -271,14 +243,9 @@ defmodule Ash.SubjectTest do
271243
subject = new_subject(subject_type)
272244

273245
# Set an argument that works for all types
274-
result =
275-
case subject_type do
276-
Ash.ActionInput -> Ash.Subject.set_argument(subject, :name, "value")
277-
_ -> Ash.Subject.set_argument(subject, :test_arg, "value")
278-
end
246+
result = %{subject | arguments: %{"name" => "value"}}
279247

280-
expected_arg_str = if subject_type == Ash.ActionInput, do: "name", else: "test_arg"
281-
assert {:ok, "value"} = Ash.Subject.fetch_argument(result, expected_arg_str)
248+
assert {:ok, "value"} = Ash.Subject.fetch_argument(result, :name)
282249
assert is_struct(result, subject_type)
283250
end
284251
end

0 commit comments

Comments
 (0)