EctoEnumerize
========
[![Hex.pm version](https://img.shields.io/hexpm/v/ecto_enumerize.svg?style=flat)](https://hex.pm/packages/ecto_enumerize)
EctoEnumerize allows to define custom enums (keyword lists) to be used in your Ecto schemes.
## Why?
It differs from [EctoEnum](https://github.com/gjaldon/ecto_enum) because
EctoEnumerize does not use the PostgreSQL native *Enum* type, instead it stores
the value as an integer and therefore it should work on any database.
While it's easy to add new values to your Enum when using PostgreSQL native Enum type,
it appears there is no easy solution to remove them without having to drop and create the enum again.
Check this [thread](https://stackoverflow.com/questions/25811017/how-to-delete-an-enum-type-value-in-postgres#25812436)
on stackoverflow for more info.
It does not affect this library since the Enum is handled at the application level.
## Usage
First, we add `ecto_enumerize` to `mix.exs`:
```elixir
def deps do
[
{:ecto_enumerize, "~> 0.1.1"}
]
end
```
Run `mix deps.get` to install `ecto_enumerize`.
Now we can define our enum as follow:
```elixir
defmodule Order do
use Ecto.Schema
import EctoEnumerize
defenum Status, pending: 0, shipped: 1, delivered: 2
schema "orders" do
field :status, Status, default: :pending
end
def changeset(order, attrs) do
cast(order, attrs, [:status])
end
end
```
In the above example, the `:status` will behave like an enum and will allow you to
pass an `integer`, `atom` or `string` to it. This applies to saving the model,
invoking `Ecto.Changeset.cast/4`, or performing a query on the status field.
Some examples:
```elixir
iex> Order.Status.get_enum()
[pending: 0, shipped: 1, delivered: 2]
iex> order = Repo.insert!(%Order{status: :delivered})
iex> Repo.get(Order, order.id).status
:delivered
iex> # any of these values will produce the same result
iex> s = Enum.random([:delivered, "delivered", 2])
iex> from(o in Order, where: o.status == ^s) |> Repo.aggregate(:count, :id)
1
```
Passing an invalid value to a `Ecto.Changeset.cast/3` will add an error to
`changeset.errors` field.
```elixir
iex> cs = Order.changeset(order, %{status: :unknown})
iex> cs.errors
[status: {"is invalid", [type: Order.Status, validation: :cast]}]
```
### Migrations
Simple as that:
```elixir
def change do
create table(:orders) do
add :status, :integer
end
end
```
## Important links
* [Documentation](http://hexdocs.pm/ecto_enumerize)
* [License](https://github.com/sgessa/ecto-enumerize/blob/master/LICENSE)