mirror of
https://github.com/ash-project/ash_graphql.git
synced 2024-09-20 05:13:33 +12:00
chore: test enums, add a guide
This commit is contained in:
parent
e8797f80da
commit
c59658b1ff
6 changed files with 168 additions and 0 deletions
75
documentation/introduction/enums.md
Normal file
75
documentation/introduction/enums.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Enums
|
||||
|
||||
## Automatically created enums
|
||||
|
||||
Enums are implemented automatically for any `atom` attribute with a `one_of` constraint. For example:
|
||||
|
||||
```elixir
|
||||
# On the resource of type `:ticket`
|
||||
attribute :type, :atom, one_of: [:foo, :bar, :baz]
|
||||
```
|
||||
|
||||
This would produce an enum called `:ticket_type`/`TicketType`.
|
||||
|
||||
## Custom enums
|
||||
|
||||
You can implement a custom enum by first adding the enum type to your absinthe schema (more [here](https://hexdocs.pm/absinthe/Absinthe.Type.Enum.html)). Then you can define a custom Ash type that refers to that absinthe enum type.
|
||||
|
||||
```elixir
|
||||
# In your absinthe schema:
|
||||
|
||||
enum :status do
|
||||
value(:open, description: "The post is open")
|
||||
value(:closed, description: "The post is closed")
|
||||
end
|
||||
```
|
||||
|
||||
```elixir
|
||||
# Your cusotm Ash Type
|
||||
defmodule AshGraphql.Test.Status do
|
||||
use Ash.Type
|
||||
|
||||
@values [:open, :closed]
|
||||
@string_values Enum.map(@values, &to_string/1)
|
||||
|
||||
def graphql_input_type(_), do: :status
|
||||
def graphql_type(_), do: :status
|
||||
|
||||
@impl true
|
||||
def storage_type, do: :string
|
||||
|
||||
@impl true
|
||||
def cast_input(value, _) when value in @values do
|
||||
{:ok, value}
|
||||
end
|
||||
|
||||
def cast_input(value, _) when is_binary(value) do
|
||||
value = String.downcase(value)
|
||||
|
||||
if value in @string_values do
|
||||
{:ok, String.to_existing_atom(value)}
|
||||
else
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def cast_stored(value, _) when value in @values do
|
||||
{:ok, value}
|
||||
end
|
||||
|
||||
def cast_stored(value, _) when value in @string_values do
|
||||
{:ok, String.to_existing_atom(value)}
|
||||
rescue
|
||||
ArgumentError ->
|
||||
:error
|
||||
end
|
||||
|
||||
@impl true
|
||||
def dump_to_native(value, _) when is_atom(value) do
|
||||
{:ok, to_string(value)}
|
||||
end
|
||||
|
||||
def dump_to_native(_, _), do: :error
|
||||
end
|
||||
```
|
|
@ -158,4 +158,42 @@ defmodule AshGraphql.CreateTest do
|
|||
}
|
||||
} = result
|
||||
end
|
||||
|
||||
test "custom enums are used" do
|
||||
resp =
|
||||
"""
|
||||
mutation CreatePost($input: CreatePostInput) {
|
||||
createPost(input: $input) {
|
||||
result{
|
||||
text
|
||||
status
|
||||
}
|
||||
errors{
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|> Absinthe.run(AshGraphql.Test.Schema,
|
||||
variables: %{
|
||||
"input" => %{
|
||||
"text" => "foobar",
|
||||
"confirmation" => "foobar",
|
||||
"status" => "OPEN"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
assert {:ok, result} = resp
|
||||
|
||||
refute Map.has_key?(result, :errors)
|
||||
|
||||
assert %{
|
||||
data: %{
|
||||
"createPost" => %{
|
||||
"result" => %{"text" => "foobar", "status" => "OPEN"}
|
||||
}
|
||||
}
|
||||
} = result
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,6 +51,7 @@ defmodule AshGraphql.Test.Post do
|
|||
attribute(:text, :string)
|
||||
attribute(:published, :boolean, default: false)
|
||||
attribute(:foo, AshGraphql.Test.Foo)
|
||||
attribute(:status, AshGraphql.Test.Status)
|
||||
end
|
||||
|
||||
calculations do
|
||||
|
|
|
@ -17,6 +17,11 @@ defmodule AshGraphql.Test.Schema do
|
|||
field(:bar, non_null(:string))
|
||||
end
|
||||
|
||||
enum :status do
|
||||
value(:open, description: "The post is open")
|
||||
value(:closed, description: "The post is closed")
|
||||
end
|
||||
|
||||
query do
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
defmodule AshGraphql.Test.Foo do
|
||||
@moduledoc false
|
||||
|
||||
use Ash.Type
|
||||
|
||||
def graphql_type(_), do: :foo
|
||||
|
|
47
test/support/types/status.ex
Normal file
47
test/support/types/status.ex
Normal file
|
@ -0,0 +1,47 @@
|
|||
defmodule AshGraphql.Test.Status do
|
||||
@moduledoc false
|
||||
use Ash.Type
|
||||
|
||||
@values [:open, :closed]
|
||||
@string_values Enum.map(@values, &to_string/1)
|
||||
|
||||
def graphql_input_type(_), do: :status
|
||||
def graphql_type(_), do: :status
|
||||
|
||||
@impl true
|
||||
def storage_type, do: :string
|
||||
|
||||
@impl true
|
||||
def cast_input(value, _) when value in @values do
|
||||
{:ok, value}
|
||||
end
|
||||
|
||||
def cast_input(value, _) when is_binary(value) do
|
||||
value = String.downcase(value)
|
||||
|
||||
if value in @string_values do
|
||||
{:ok, String.to_existing_atom(value)}
|
||||
else
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def cast_stored(value, _) when value in @values do
|
||||
{:ok, value}
|
||||
end
|
||||
|
||||
def cast_stored(value, _) when value in @string_values do
|
||||
{:ok, String.to_existing_atom(value)}
|
||||
rescue
|
||||
ArgumentError ->
|
||||
:error
|
||||
end
|
||||
|
||||
@impl true
|
||||
def dump_to_native(value, _) when is_atom(value) do
|
||||
{:ok, to_string(value)}
|
||||
end
|
||||
|
||||
def dump_to_native(_, _), do: :error
|
||||
end
|
Loading…
Reference in a new issue