improvment: loading data shouldn't call before action hooks

by this, I mean that loading data shouldn't call before action
hooks on the root resource you're loading data on
This commit is contained in:
Zach Daniel 2023-04-01 01:35:12 -04:00
parent a9db35e79f
commit f832ab3624
2 changed files with 77 additions and 57 deletions

View file

@ -286,6 +286,25 @@ defmodule Ash.Actions.Read do
query = add_calculation_context(query, actor, authorize?, tenant, tracer) query = add_calculation_context(query, actor, authorize?, tenant, tracer)
if Keyword.has_key?(request_opts, :initial_data) do
query
|> Ash.Query.set_context(%{
initial_limit: query.limit,
initial_offset: query.offset,
page_opts: nil,
initial_query: query,
filter_requests: [],
query_opts: query_opts
})
|> query_with_initial_data(request_opts)
|> case do
%{valid?: true} = query ->
{:ok, query}
%{valid?: false} = query ->
{:error, query.errors, %{set: %{query: query}}}
end
else
query = %{ query = %{
query query
| api: api, | api: api,
@ -303,9 +322,7 @@ defmodule Ash.Actions.Read do
%{limit: initial_limit, offset: initial_offset} <- query, %{limit: initial_limit, offset: initial_offset} <- query,
%{valid?: true} = query <- %{valid?: true} = query <-
handle_attribute_multitenancy(query), handle_attribute_multitenancy(query),
:ok <- validate_multitenancy(query, initial_data), :ok <- validate_multitenancy(query),
%{valid?: true} = query <-
query_with_initial_data(query, request_opts),
{%{valid?: true} = query, before_notifications} <- {%{valid?: true} = query, before_notifications} <-
run_before_action(query), run_before_action(query),
{:ok, initial_query, query, page_opts} <- {:ok, initial_query, query, page_opts} <-
@ -345,6 +362,7 @@ defmodule Ash.Actions.Read do
other other
end end
end end
end
), ),
authorize?: !Keyword.has_key?(request_opts, :initial_data), authorize?: !Keyword.has_key?(request_opts, :initial_data),
data: data_field(request_opts, path, error_path), data: data_field(request_opts, path, error_path),
@ -586,10 +604,9 @@ defmodule Ash.Actions.Read do
end end
end end
defp validate_multitenancy(query, initial_data) do defp validate_multitenancy(query) do
if is_nil(Ash.Resource.Info.multitenancy_strategy(query.resource)) || if is_nil(Ash.Resource.Info.multitenancy_strategy(query.resource)) ||
Ash.Resource.Info.multitenancy_global?(query.resource) || query.tenant || Ash.Resource.Info.multitenancy_global?(query.resource) || query.tenant do
initial_data do
:ok :ok
else else
{:error, Ash.Error.Invalid.TenantRequired.exception(resource: query.resource)} {:error, Ash.Error.Invalid.TenantRequired.exception(resource: query.resource)}

View file

@ -385,7 +385,8 @@ defmodule Ash.Query do
end end
end end
defp set_actor(query, opts) do @doc false
def set_actor(query, opts) do
if Keyword.has_key?(opts, :actor) do if Keyword.has_key?(opts, :actor) do
put_context(query, :private, %{actor: opts[:actor]}) put_context(query, :private, %{actor: opts[:actor]})
else else
@ -393,7 +394,8 @@ defmodule Ash.Query do
end end
end end
defp set_authorize?(query, opts) do @doc false
def set_authorize?(query, opts) do
if Keyword.has_key?(opts, :authorize?) do if Keyword.has_key?(opts, :authorize?) do
put_context(query, :private, %{authorize?: opts[:authorize?]}) put_context(query, :private, %{authorize?: opts[:authorize?]})
else else
@ -401,7 +403,8 @@ defmodule Ash.Query do
end end
end end
defp set_tracer(query, opts) do @doc false
def set_tracer(query, opts) do
if Keyword.has_key?(opts, :tracer) do if Keyword.has_key?(opts, :tracer) do
put_context(query, :private, %{tracer: opts[:tracer]}) put_context(query, :private, %{tracer: opts[:tracer]})
else else