Latest commit d28f8b3 Jan 18, 2017 @gjaldon committed on GitHub Merge pull request #34 from sztosz/readme-migration-typo-fix
Fix crucial typo in readme



Hex.pm version Hex.pm downloads Inline docs Build Status

EctoEnum is an Ecto extension to support enums in your Ecto models.


First, we add ecto_enum to mix.exs:

def deps do
  [{:ecto_enum, "~> 1.0"}]

We will then have to define our enum. We can do this in a separate file since defining an enum is just defining a module. We do it like:

# lib/my_app/ecto_enums.ex

import EctoEnum
defenum StatusEnum, registered: 0, active: 1, inactive: 2, archived: 3

Once defined, EctoEnum can be used like any other Ecto.Type by passing it to a field in your model's schema block. For example:

defmodule User do
  use Ecto.Model

  schema "users" do
    field :status, StatusEnum

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:

iex> user = Repo.insert!(%User{status: 0})
iex> Repo.get(User, user.id).status

iex> %{changes: changes} = cast(%User{}, %{"status" => "active"}, ~w(status), [])
iex> changes.status

iex> from(u in User, where: u.status == ^:registered) |> Repo.all() |> length

Passing a value that the custom Enum type does not recognize will result in an error.


The enum type StatusEnum will also have a reflection function for inspecting the enum map in runtime.

iex> StatusEnum.__enum_map__()
[registered: 0, active: 1, inactive: 2, archived: 3]
iex> StatusEnum.__valid_values__()
[0, 1, 2, 3, :registered, :active, :inactive, :archived, "active", "archived",
"inactive", "registered"]

Using Postgres's Enum Type

Enumerated Types in Postgres are now supported. To use Postgres's Enum Type with EctoEnum, use the defenum/3 macro instead of defenum/2. We do it like:

# lib/my_app/ecto_enums.ex

import EctoEnum
defenum StatusEnum, :status, [:registered, :active, :inactive, :archived]

The second argument is the name you want used for the new type you are creating in Postgres. Note that defenum/3 expects a list of atoms(could be strings) instead of a keyword list unlike in defenum/2. Another notable difference is that you can no longer use integers in place of atoms or strings as values in your enum type. Given the above code, this means that you can only pass the following values:

[:registered, :active, :inactive, :archived, "registered", "active", "inactive", "archived"]

In your migrations, you can make use of helper functions like:

def up do
  create table(:users_pg) do
    add :status, :status

def down do
  drop table(:users_pg)

create_type/0 and drop_type/0 are automatically defined for you in your custom Enum module.

Important links