How to use one Enum value for REST/GraphQL, serialized as another to the database

Hello all, I'm still new to Elixir and the Ash framework. I'm trying to create a set of values to use for both the REST and GraphQL interfaces of my API to have values spelt out such as north, north_east, etc. spelt out. However when I read or write that field to the database, I'd like to have it serialized as string values such as N, NE, etc. Here's the code I have so far:
defmodule My.Direction do
use Ash.Type.Enum
values: [
:north,
:north_east,
:east,
:south_east,
:south,
:south_west,
:west,
:north_west
]

use AshGraphql.Type

def storage_type(), do: :string

@impl AshGraphql.Type
def graphql_type(_), do: :direction
end


defmodule My.BoatPath do
use Ash.Resource
...

attributes do
...
attribute :direction, My.Direction do
allow_nil? true
public? true
end
...
end
end
defmodule My.Direction do
use Ash.Type.Enum
values: [
:north,
:north_east,
:east,
:south_east,
:south,
:south_west,
:west,
:north_west
]

use AshGraphql.Type

def storage_type(), do: :string

@impl AshGraphql.Type
def graphql_type(_), do: :direction
end


defmodule My.BoatPath do
use Ash.Resource
...

attributes do
...
attribute :direction, My.Direction do
allow_nil? true
public? true
end
...
end
end
I've tried things like overriding Ecto.type definitions for load/1, dump/1 but it keeps failing on me when I try to load an existing database record with a direction field value of NE:
** (ArgumentError) cannot load `"NE"` as type #My.Direction.EctoType<[]> for field :direction in %My.BoatPath{... direction: nil, ..., __meta__: #Ecto.Schema.Metadata<:loaded, "BOAT_PATH">}
** (ArgumentError) cannot load `"NE"` as type #My.Direction.EctoType<[]> for field :direction in %My.BoatPath{... direction: nil, ..., __meta__: #Ecto.Schema.Metadata<:loaded, "BOAT_PATH">}
Solution:
You can override the cast_stored and dump_to_native callbacks on the type
Jump to solution
1 Reply
Solution
ZachDaniel
ZachDaniel3mo ago
You can override the cast_stored and dump_to_native callbacks on the type

Did you find this page helpful?