Just in case anyone is looking for a way to use postgres enum types with ecto, here’s how (without any additional dependencies).
defmodule Invoice.Status do
@moduledoc """
The status of payment; whether the invoice has been paid or not.
Enumeration members:
- `:payment_automatically_applied`
- `:payment_complete`
- `:payment_declined`
- `:payment_due`
- `:payment_past_due`
"""
@behaviour Ecto.Type
statuses = [
:payment_automatically_applied,
:payment_complete,
:payment_declined,
:payment_due,
:payment_past_due
] |> Enum.map(fn status ->
{status, to_string(status)}
end)
@doc "Returns the underlying schema type for the custom type"
@spec type :: :invoice_status
def type, do: :invoice_status
@doc "Casts the given input to the custom type"
@spec cast(atom | binary) :: {:ok, atom} | :error
def cast(status)
for {atom, string} <- statuses do
def cast(unquote(atom)), do: {:ok, unquote(atom)}
def cast(unquote(string)), do: {:ok, unquote(atom)}
end
def cast(_other), do: :error
@doc "Loads the given term into a custom type"
@spec load(binary) :: {:ok, atom}
def load(status)
for {atom, string} <- statuses do
def load(unquote(string)), do: {:ok, unquote(atom)}
end
@doc "Dumps the given term into an Ecto native type"
@spec dump(atom | binary) :: {:ok, binary} | :error
def dump(status)
for {atom, string} <- statuses do
def dump(unquote(atom)), do: {:ok, unquote(string)}
def dump(unquote(string)), do: {:ok, unquote(string)}
end
def dump(_other), do: :error
end