README.md

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.

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.

When using native `Enum` types, you would need to tell PostgreSQL all the possible
values of your Enum and in order to add new values you would need to alter the
table definition. At the moment PostgreSQL does not support dropping a value
from an existing enum.

Check this [thread](https://stackoverflow.com/questions/25811017/how-to-delete-an-enum-type-value-in-postgres#25812436)
on stackoverflow for more info.

## Usage

First, we add `ecto_enumerize` to `mix.exs`:

```elixir
def deps do
  [
    {:ecto_enumerize, "~> 0.1.0"}
  ]
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. Let's
do a few examples:

```elixir
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

In your migrations:

```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)