ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - gjaldon/ecto_enum: Ecto extension to support enums in models
Ecto extension to support enums in models. Contribute to gjaldon/ecto_enum development by creating an account on GitHub.
Visit Site

GitHub - gjaldon/ecto_enum: Ecto extension to support enums in models

GitHub - gjaldon/ecto_enum: Ecto extension to support enums in models

EctoEnum

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

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

Usage

First, we add ecto_enum to mix.exs:

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

Run mix deps.get to install ecto_enum.

Creating an Ecto Enum with defenum/2 macro

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

Note that we can also use string-backed enums by doing the following:

defenum StatusEnum, registered: "registered", active: "active", inactive: "active", archived: "archived"
# short-cut way of using string-backed enums
defenum StatusEnum, ["registered", "active", "inactive", "archived"]

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.Schema

  schema "users" do
    field :status, StatusEnum
  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:

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

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

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

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

Creating an Ecto Enum by useing EctoEnum

Another way to create an Ecto Enum is by useing the EctoEnum or the EctoEnum.Postgres modules.

To use EctoEnum with integer-backed storage:

defmodule CustomEnum do
  use EctoEnum, ready: 0, set: 1, go: 2
end

To use EctoEnum with string-backed storage:

defmodule CustomEnum do
  use EctoEnum, "ready", "set", "go"
end

To use EctoEnum with Postgres user-defined types:

defmodule PostgresType do
  use EctoEnum, type: :new_type, enums: [:ready, :set, :go]
end

We can also use EctoEnum.Postgres directly like:

defmodule NewType do
  use EctoEnum.Postgres, type: :new_type, enums: [:ready, :set, :go]
end

Reflection

The enum type StatusEnum will also have a reflection function for inspecting the enum map at 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"]

There is also a helper function that leverages the __valid_values__() reflection called valid_value?(value).

iex> StatusEnum.valid_value?(:registered)
true
iex> StatusEnum.valid_value?("invalid")
false

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 to use 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 change do
  StatusEnum.create_type
  create table(:users_pg) do
    add :status, StatusEnum.type()
  end
end

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

You can also create the enum in a different schema:

defenum StatusEnum, :status, [:registered, :active, :inactive, :archived], schema: "alternative_schema"

Important notes/gotchas

Postgres

  • Keep in mind that ALTER TYPE ... ADD VALUE cannot be executed inside a transaction block. This means that running this inside a migration requires you to set to the module attribute @disable_ddl_transaction to true. For example:
defmodule MyApp.Repo.Migrations.AddToGenderEnum do
  use Ecto.Migration
  @disable_ddl_transaction true

  def up do
    Ecto.Migration.execute "ALTER TYPE gender ADD VALUE IF NOT EXISTS'other'"
  end

  def down do
  end
end
  • Note that there is no easy way to drop an enum value. It is not supported and you must create a new type without the value. Here are some work-arounds. Best to avoid having to drop an enum value.

Important links

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory