{"id":13508788,"url":"https://github.com/gjaldon/ecto_enum","last_synced_at":"2025-05-14T19:10:05.050Z","repository":{"id":34709443,"uuid":"38685833","full_name":"gjaldon/ecto_enum","owner":"gjaldon","description":"Ecto extension to support enums in models","archived":false,"fork":false,"pushed_at":"2024-05-28T10:59:28.000Z","size":177,"stargazers_count":565,"open_issues_count":23,"forks_count":130,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-11T10:00:43.541Z","etag":null,"topics":["custom-enum","ecto","ecto-extension","elixir","enum","postgres-enum"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gjaldon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-07T12:21:51.000Z","updated_at":"2025-04-07T16:21:13.000Z","dependencies_parsed_at":"2024-06-18T12:33:33.314Z","dependency_job_id":"6eb62a71-5210-40e3-b0c4-d5d021f5b335","html_url":"https://github.com/gjaldon/ecto_enum","commit_stats":{"total_commits":142,"total_committers":33,"mean_commits":4.303030303030303,"dds":0.352112676056338,"last_synced_commit":"12671845b216d80a8f02cc557207442208dbfffa"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjaldon%2Fecto_enum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjaldon%2Fecto_enum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjaldon%2Fecto_enum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjaldon%2Fecto_enum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gjaldon","download_url":"https://codeload.github.com/gjaldon/ecto_enum/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-enum","ecto","ecto-extension","elixir","enum","postgres-enum"],"created_at":"2024-08-01T02:00:58.449Z","updated_at":"2025-05-14T19:10:02.917Z","avatar_url":"https://github.com/gjaldon.png","language":"Elixir","funding_links":[],"categories":["ORM and Datamapping","Uncategorized"],"sub_categories":["Uncategorized"],"readme":"EctoEnum\n========\n\n[![Hex.pm version](https://img.shields.io/hexpm/v/ecto_enum.svg?style=flat)](https://hex.pm/packages/ecto_enum)\n[![Hex.pm downloads](https://img.shields.io/hexpm/dt/ecto_enum.svg?style=flat)](https://hex.pm/packages/ecto_enum)\n[![Inline docs](http://inch-ci.org/github/gjaldon/ecto_enum.svg?branch=master)](http://inch-ci.org/github/gjaldon/ecto_enum)\n[![Build Status](https://travis-ci.org/gjaldon/ecto_enum.svg?branch=master)](https://travis-ci.org/gjaldon/ecto_enum)\n\nEctoEnum is an Ecto extension to support enums in your Ecto models.\n\n## Usage\n\nFirst, we add `ecto_enum` to `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:ecto_enum, \"~\u003e 1.4\"}\n  ]\nend\n```\n\nRun `mix deps.get` to install `ecto_enum`.\n\n### Creating an Ecto Enum with `defenum/2` macro\n\nWe will then have to define our enum. We can do this in a separate file since defining\nan enum is just defining a module. We do it like:\n\n```elixir\n# lib/my_app/ecto_enums.ex\n\nimport EctoEnum\ndefenum StatusEnum, registered: 0, active: 1, inactive: 2, archived: 3\n```\n\nNote that we can also use string-backed enums by doing the following:\n\n```elixir\ndefenum StatusEnum, registered: \"registered\", active: \"active\", inactive: \"active\", archived: \"archived\"\n# short-cut way of using string-backed enums\ndefenum StatusEnum, [\"registered\", \"active\", \"inactive\", \"archived\"]\n```\n\nOnce defined, `EctoEnum` can be used like any other `Ecto.Type` by passing it to a field\nin your model's schema block. For example:\n\n```elixir\ndefmodule User do\n  use Ecto.Schema\n\n  schema \"users\" do\n    field :status, StatusEnum\n  end\nend\n```\n\nIn the above example, the `:status` will behave like an enum and will allow you to\npass an `integer`, `atom` or `string` to it. This applies to saving the model,\ninvoking `Ecto.Changeset.cast/4`, or performing a query on the status field. Let's\ndo a few examples:\n\n```elixir\niex\u003e user = Repo.insert!(%User{status: 0})\niex\u003e Repo.get(User, user.id).status\n:registered\n\niex\u003e %{changes: changes} = cast(%User{}, %{\"status\" =\u003e \"active\"}, ~w(status), [])\niex\u003e changes.status\n:active\n\niex\u003e from(u in User, where: u.status == ^:registered) |\u003e Repo.all() |\u003e length\n1\n```\n\nPassing a value that the custom Enum type does not recognize will result in an error.\n\n### Creating an Ecto Enum by `use`ing `EctoEnum`\n\nAnother way to create an Ecto Enum is by `use`ing the `EctoEnum` or the `EctoEnum.Postgres`\nmodules.\n\nTo `use` `EctoEnum` with integer-backed storage:\n\n```elixir\ndefmodule CustomEnum do\n  use EctoEnum, ready: 0, set: 1, go: 2\nend\n```\n\nTo `use` `EctoEnum` with string-backed storage:\n\n```elixir\ndefmodule CustomEnum do\n  use EctoEnum, \"ready\", \"set\", \"go\"\nend\n```\n\nTo `use` `EctoEnum` with Postgres user-defined types:\n\n```elixir\ndefmodule PostgresType do\n  use EctoEnum, type: :new_type, enums: [:ready, :set, :go]\nend\n```\n\nWe can also `use` `EctoEnum.Postgres` directly like:\n\n```elixir\ndefmodule NewType do\n  use EctoEnum.Postgres, type: :new_type, enums: [:ready, :set, :go]\nend\n```\n\n### Reflection\n\nThe enum type `StatusEnum` will also have a reflection function for inspecting the\nenum map at runtime.\n\n```elixir\niex\u003e StatusEnum.__enum_map__()\n[registered: 0, active: 1, inactive: 2, archived: 3]\niex\u003e StatusEnum.__valid_values__()\n[0, 1, 2, 3, :registered, :active, :inactive, :archived, \"active\", \"archived\",\n\"inactive\", \"registered\"]\n```\n\nThere is also a helper function that leverages the `__valid_values__()` reflection called `valid_value?(value)`.\n\n```elixir\niex\u003e StatusEnum.valid_value?(:registered)\ntrue\niex\u003e StatusEnum.valid_value?(\"invalid\")\nfalse\n```\n\n### Using Postgres's Enum Type\n\n[Enumerated Types in Postgres](https://www.postgresql.org/docs/current/static/datatype-enum.html) are now supported. To use Postgres's Enum Type with EctoEnum, use the `defenum/3` macro\ninstead of `defenum/2`. We do it like:\n\n```elixir\n# lib/my_app/ecto_enums.ex\n\nimport EctoEnum\ndefenum StatusEnum, :status, [:registered, :active, :inactive, :archived]\n```\n\nThe second argument is the name you want to use for the new type you are creating in Postgres.\nNote that `defenum/3` expects a list of atoms(could be strings) instead of a keyword\nlist unlike in `defenum/2`. Another notable difference is that you can no longer\nuse integers in place of atoms or strings as values in your enum type. Given the\nabove code, this means that you can only pass the following values:\n\n```elixir\n[:registered, :active, :inactive, :archived, \"registered\", \"active\", \"inactive\", \"archived\"]\n```\n\nIn your migrations, you can make use of helper functions like:\n\n```elixir\ndef change do\n  StatusEnum.create_type\n  create table(:users_pg) do\n    add :status, StatusEnum.type()\n  end\nend\n```\n\n`create_type/0`, `type/0` and `drop_type/0` are automatically defined for you in\nyour custom Enum module.\n\nYou can also create the enum in a different schema:\n```elixir\ndefenum StatusEnum, :status, [:registered, :active, :inactive, :archived], schema: \"alternative_schema\"\n```\n\n## Important notes/gotchas\n\n### Postgres\n- 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:\n\n```elixir\ndefmodule MyApp.Repo.Migrations.AddToGenderEnum do\n  use Ecto.Migration\n  @disable_ddl_transaction true\n\n  def up do\n    Ecto.Migration.execute \"ALTER TYPE gender ADD VALUE IF NOT EXISTS'other'\"\n  end\n\n  def down do\n  end\nend\n```\n- 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](http://stackoverflow.com/questions/25811017/how-to-delete-an-enum-type-in-postgres) are some work-arounds. Best to avoid having to drop an enum value.\n\n## Important links\n\n  * [Documentation](http://hexdocs.pm/ecto_enum)\n  * [License](https://github.com/gjaldon/ecto_enum/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgjaldon%2Fecto_enum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgjaldon%2Fecto_enum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgjaldon%2Fecto_enum/lists"}