-
-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improvement: warning on args, preparations or filters on primary reads
Probably one of the most common mistakes made in early days of Ash is accidentally adding preparations, filters, or arguments to the primary read actions. This adds a dismissable warning to help prevent this case.
- Loading branch information
1 parent
a325ac7
commit e5656b6
Showing
3 changed files
with
61 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
lib/ash/resource/verifiers/verify_primary_read_action_has_no_arguments.ex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
defmodule Ash.Resource.Verifiers.VerifyPrimaryReadActionHasNoArguments do | ||
@moduledoc "Verifies that primary read actions do not have any arguments" | ||
use Spark.Dsl.Verifier | ||
|
||
def verify(dsl) do | ||
resource = Spark.Dsl.Verifier.get_persisted(dsl, :module) | ||
|
||
if Spark.Dsl.Verifier.get_persisted(dsl, :primary_read_warning?) do | ||
dsl | ||
|> Ash.Resource.Info.actions() | ||
|> Enum.find(&(&1.type == :read && &1.primary?)) | ||
|> case do | ||
nil -> | ||
:ok | ||
|
||
action -> | ||
if action.arguments != [] do | ||
IO.warn(warning(resource, action, "arguments")) | ||
end | ||
|
||
if action.filter not in [nil, []] do | ||
IO.warn(warning(resource, action, "filters")) | ||
end | ||
|
||
if action.preparations != [] && | ||
Ash.Resource.Info.data_layer(resource) != Ash.DataLayer.Simple do | ||
IO.warn(warning(resource, action, "preparations")) | ||
end | ||
|
||
:ok | ||
end | ||
else | ||
:ok | ||
end | ||
end | ||
|
||
defp warning(resource, action, things) do | ||
""" | ||
Primary read action `#{inspect(resource)}.#{action.name}` has #{things}. | ||
This is often done by mistake, but can also be done intentionally. | ||
Primary read actions are used when loading relationships, checking policies and more. | ||
It is okay to have optional arguments, but required arguments are almost never desired. | ||
If you intended to have #{things} on your primary read action, add `primary_read_warning?: false` | ||
to `use Ash.Resource`. For example: | ||
use Ash.Resource, | ||
primary_read_warning?: false | ||
""" | ||
end | ||
end |