Created
October 29, 2016 07:31
-
-
Save syamilmj/bbd8dd5b06c6ca7d1c2fa63e36df0d2d to your computer and use it in GitHub Desktop.
Add enum datatype support to Ecto
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
defmodule Inventory.Enum do | |
@moduledoc """ | |
Provides macro to support Enum datatype with Ecto | |
## Usage | |
In your model: | |
import Inventory.Enum | |
defenum MyEnumStatus, draft: 0, published: 1, archive: 2 | |
schema "posts" do | |
field :status, MyEnumStatus | |
end | |
To query: | |
from p in Post, where: p.status == ^:published | |
""" | |
defmacro defenum(module, enum) do | |
quote do | |
list = unquote(enum) |> Macro.escape | |
defmodule unquote(module) do | |
@behaviour Ecto.Type | |
@keylist for {k,v} <- list, into: %{}, do: {k,v} | |
@vallist for {k,v} <- list, into: %{}, do: {v,k} | |
def type, do: :integer | |
def cast(key) when is_atom(key) do | |
fetch(key, @keylist) | |
end | |
def cast(integer) when is_integer(integer), do: {:ok, integer} | |
def cast(_), do: :error | |
def load(val) when is_integer(val) do | |
fetch(val, @vallist) | |
end | |
def dump(integer) when is_integer(integer), do: {:ok, integer} | |
def dump(_), do: :error | |
defp fetch(key, map) do | |
if key in Map.keys(map) do | |
{:ok, Map.get(map, key)} | |
else | |
:error | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment