{"id":13508811,"url":"https://github.com/gpedic/ecto_shortuuid","last_synced_at":"2025-10-21T17:04:08.546Z","repository":{"id":34066914,"uuid":"168231712","full_name":"gpedic/ecto_shortuuid","owner":"gpedic","description":"Ecto type which adds support for ShortUUID in Ecto schemas","archived":false,"fork":false,"pushed_at":"2024-12-28T13:58:37.000Z","size":30,"stargazers_count":29,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-01T07:05:47.176Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/gpedic.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}},"created_at":"2019-01-29T21:27:00.000Z","updated_at":"2025-02-17T18:50:03.000Z","dependencies_parsed_at":"2024-01-08T19:22:17.654Z","dependency_job_id":null,"html_url":"https://github.com/gpedic/ecto_shortuuid","commit_stats":{"total_commits":17,"total_committers":3,"mean_commits":5.666666666666667,"dds":"0.11764705882352944","last_synced_commit":"a114ce102e4dd08cbc3059038021097053b49ffd"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpedic%2Fecto_shortuuid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpedic%2Fecto_shortuuid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpedic%2Fecto_shortuuid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpedic%2Fecto_shortuuid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gpedic","download_url":"https://codeload.github.com/gpedic/ecto_shortuuid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246314013,"owners_count":20757453,"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":[],"created_at":"2024-08-01T02:00:58.792Z","updated_at":"2025-10-21T17:04:08.536Z","avatar_url":"https://github.com/gpedic.png","language":"Elixir","funding_links":[],"categories":["ORM and Datamapping"],"sub_categories":[],"readme":"[![CI](https://github.com/gpedic/ecto_shortuuid/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/gpedic/ecto_shortuuid/actions/workflows/ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/gpedic/ecto_shortuuid/badge.svg?branch=master)](https://coveralls.io/github/gpedic/ecto_shortuuid?branch=master)\n[![Hex.pm](https://img.shields.io/hexpm/v/ecto_shortuuid.svg)](https://hex.pm/packages/ecto_shortuuid)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/ecto_shortuuid/)\n[![License](https://img.shields.io/hexpm/l/ecto_shortuuid.svg)](https://github.com/gpedic/ecto_shortuuid/blob/master/LICENSE.md)\n[![Last Updated](https://img.shields.io/github/last-commit/gpedic/ecto_shortuuid.svg)](https://github.com/gpedic/ecto_shortuuid/commits/master)\n\n# Ecto.ShortUUID\n\nEcto.ShortUUID is a custom [Ecto.Type](https://hexdocs.pm/ecto/Ecto.Type.html#content) which allows for Ecto to automatically encode UUIDs to [ShortUUIDs](https://github.com/gpedic/ex_shortuuid).\n\nShortUUID is binary-compatible with UUID, so it can be stored in a `uuid` column in a database.\n\nShortUUIDs can be used alongside `:binary_id` or as drop-in replacement for `:binary_id` primary and foreign keys, basically anywhere Ecto.UUID can be used.\n\nIf you're already using `:binary_id`(`Ecto.UUID`) for primary keys it is possible to simply switch from `:binary_id` to using `Ecto.ShortUUID` and vice versa, neither the underlying data nor DB schema need to be changed.\n\nFor example, we can see that calls to `Ecto.ShortUUID.dump/1` and `Ecto.UUID.dump/1` will  return the same binary in the following case:\n\n```elixir\n# let's get the encoded value\niex\u003e Ecto.ShortUUID.cast(\"2a162ee5-02f4-4701-9e87-72762cbce5e2\")\n{:ok, \"9VprZJ9U7Tgg2PJ8BfTAek\"}\n\n# and show off that dump/1 works with both ShortUUIDs and UUIDs\niex\u003e Ecto.ShortUUID.dump(\"9VprZJ9U7Tgg2PJ8BfTAek\")\n{:ok, \u003c\u003c42, 22, 46, 229, 2, 244, 71, 1, 158, 135, 114, 118, 44, 188, 229, 226\u003e\u003e}\n\n# dump/1 continues to work with regular UUIDs\niex\u003e Ecto.ShortUUID.dump(\"2a162ee5-02f4-4701-9e87-72762cbce5e2\")\n{:ok, \u003c\u003c42, 22, 46, 229, 2, 244, 71, 1, 158, 135, 114, 118, 44, 188, 229, 226\u003e\u003e}\n\niex\u003e Ecto.UUID.dump(\"2a162ee5-02f4-4701-9e87-72762cbce5e2\")\n{:ok, \u003c\u003c42, 22, 46, 229, 2, 244, 71, 1, 158, 135, 114, 118, 44, 188, 229, 226\u003e\u003e}\n\n# when a key is retrieved load/1 is called\n# with the binary representation of the UUID 2a162ee5-02f4-4701-9e87-72762cbce5e2\niex\u003e Ecto.ShortUUID.load(\u003c\u003c42, 22, 46, 229, 2, 244, 71, 1, 158, 135, 114, 118, 44, 188, 229, 226\u003e\u003e)\n{:ok, \"9VprZJ9U7Tgg2PJ8BfTAek\"}\n\n# the same binary key continues to work with Ecto.UUID\niex\u003e Ecto.UUID.load(\u003c\u003c42, 22, 46, 229, 2, 244, 71, 1, 158, 135, 114, 118, 44, 188, 229, 226\u003e\u003e)\n{:ok, \"2a162ee5-02f4-4701-9e87-72762cbce5e2\"}\n```\nWe can see that `Ecto.ShortUUID.dump/1` is backwards compatible and still accepts regular `UUIDs` and the value stored in the DB is exactly the same as when using the regular `:binary_id` type.\n\n## Installation\n\nIf [available in Hex](https://hex.pm/docs/publish), the package can be installed\nby adding `ecto_shortuuid` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:ecto_shortuuid, \"~\u003e 0.4.0\"}\n  ]\nend\n```\n\n## Example project\n\nYou can check out the example project [ecto_shortuuid_example](https://github.com/gpedic/ecto_shortuuid_example) with defined config, schemas and seeds to quickly try out `ecto_shortuuid` for yourself.\n\n## Usage\n\nUsing Ecto.ShortUUID is similar to using Ecto.UUID.\n\n### Schema\n\nYou can use the ShortUUID for a regular field\n\n```elixir\ndefmodule Post do\n  use Ecto.Schema\n\n  schema \"posts\" do\n    field :test, Ecto.ShortUUID\n  end\nend\n```\n\nTo use ShortUUIDs as primary keys we define the @primary_key attribute like this:\n\n```elixir\ndefmodule MyApp.User do\n  use Ecto.Schema\n\n  @primary_key {:id, Ecto.ShortUUID, autogenerate: true}\n\n  schema \"users\" do\n    field :name, :string\n    field :age, :integer, default: 0\n    has_many :posts, Post\n  end\nend\n```\n\nTo avoid having to define the primary key type in every schema in case you're using binary ids throughout you can make ShortUUIDs the default by defining the following in the underlying schema module.\n\n```elixir\n# Define a module to be used as base\ndefmodule MyApp.Schema do\n  defmacro __using__(_) do\n    quote do\n      use Ecto.Schema\n      @primary_key {:id, Ecto.ShortUUID, autogenerate: true}\n      @foreign_key_type Ecto.ShortUUID\n    end\n  end\nend\n\n# Now use MyApp.Schema to define new schemas\ndefmodule MyApp.User do\n  use MyApp.Schema\n\n  schema \"users\" do\n    field :name, :string\n    field :age, :integer, default: 0\n    has_many :posts, Post\n  end\nend\n```\nThis exactly the same as when using `:binary_id` as defined in the [Ecto docs - Schema attributes](https://hexdocs.pm/ecto/Ecto.Schema.html#module-schema-attributes).\n\n\n### Migration\n\nThe key has to be also defined as :uuid in the migration\n\n```elixir\ndefmodule MyApp.Repo.Migrations.CreateUser do\n  use Ecto.Migration\n\n  def change do\n    create table(:users, primary_key: false) do\n      add :id, :uuid, primary_key: true\n      add :name, :string\n      add :age, :integer\n      add :company_id, references(:companies, type: :uuid)\n\n      timestamps\n  end\nend\n```\n\nAlternatively if starting from scratch you can configure the default migration primary key type as:\n\n```elixir\nconfig :app, MyApp.Repo,\n  migration_primary_key: [name: :id, type: :binary_id]\n```\n\nRead more about config options in the [Ecto docs - Repo Configuration](https://hexdocs.pm/ecto_sql/Ecto.Migration.html#module-repo-configuration).\n\n## Custom Alphabets\n\nStarting with version `0.4.0` Ecto.ShortUUID supports custom alphabets through two approaches.\n\u003e Note: Custom alphabets are available in [ShortUUID](https://github.com/gpedic/ex_shortuuid) starting from version 4.0.0, and the ShortUUID.Behaviour is available since version 4.1.0.\n\nTo ensure you have the right version of ShortUUID for custom alphabets, you can explicitly specify it in your dependencies:\n\n```elixir\ndef deps do\n  [\n    {:ecto_shortuuid, \"~\u003e 0.4.0\"},\n    {:shortuuid, \"~\u003e 4.1\"}  # Explicitly specify for custom alphabets/behaviors\n  ]\nend\n```\n\n### Approach 1: Using ShortUUID.Builder\n\nYou can define a custom ShortUUID module with a specific alphabet using `ShortUUID.Builder`, then create a custom Ecto type with `Ecto.ShortUUID.Builder`:\n\n```elixir\n# Define a custom ShortUUID implementation with a specific alphabet\ndefmodule MyApp.Base58UUID do\n  use ShortUUID.Builder, alphabet: :base58\nend\n\n# Create a custom Ecto type that uses your ShortUUID implementation\ndefmodule MyApp.Base58EctoUUID do\n  use Ecto.ShortUUID.Builder, encoder: MyApp.Base58UUID\nend\n\n# Use in your schema\ndefmodule MyApp.User do\n  use Ecto.Schema\n  \n  @primary_key {:id, MyApp.Base58EctoUUID, autogenerate: true}\n  @foreign_key_type MyApp.Base58EctoUUID\n  \n  schema \"users\" do\n    # ...\n  end\nend\n```\n\n[ShortUUID](https://github.com/gpedic/ex_shortuuid) supports these predefined alphabets:\n- `:base57_shortuuid` - Default alphabet, omits ambiguous characters like \"l\", \"1\", \"I\", \"O\", \"0\"\n- `:base58` - Bitcoin alphabet\n- `:base62` - Alphanumeric alphabet\n- `:base32`, `:base32_hex`, `:base32_crockford`, `:base32_z` - Various base32 encodings\n- `:base64`, `:base64_url` - Base64 encodings\n\nYou can also define a custom alphabet string with at least 16 unique characters:\n\n```elixir\ndefmodule MyApp.CustomAlphabetUUID do\n  use ShortUUID.Builder, alphabet: \"0123456789ABCDEF-_+\"\nend\n```\n\n### Approach 2: Implementing ShortUUID.Behaviour\n\nFor more control, you can implement the `ShortUUID.Behaviour` (available since [ShortUUID](https://github.com/gpedic/ex_shortuuid) v4.1.0) directly:\n\n```elixir\ndefmodule MyApp.CustomShortUUID do\n  @behaviour ShortUUID.Behaviour\n  \n  @impl true\n  def encode(uuid) do\n    # Your custom implementation\n    {:ok, \"custom-\" \u003c\u003e uuid}\n  end\n  \n  @impl true\n  def encode!(uuid) do\n    case encode(uuid) do\n      {:ok, encoded} -\u003e encoded\n      {:error, reason} -\u003e raise ArgumentError, message: reason\n    end\n  end\n  \n  @impl true\n  def decode(\"custom-\" \u003c\u003e uuid) do\n    # Your custom implementation\n    {:ok, uuid}\n  end\n  \n  @impl true\n  def decode!(encoded) do\n    case decode(encoded) do\n      {:ok, decoded} -\u003e decoded\n      {:error, reason} -\u003e raise ArgumentError, message: reason\n    end\n  end\nend\n\n# Create an Ecto type with your custom implementation\ndefmodule MyApp.CustomEctoUUID do\n  use Ecto.ShortUUID.Builder, encoder: MyApp.CustomShortUUID\nend\n```\n\nThis gives you complete control over encoding and decoding while maintaining compatibility with Ecto.\n\n## Documentation\n\nAdditional documentation can\nbe found at [https://hexdocs.pm/ecto_shortuuid](https://hexdocs.pm/ecto_shortuuid).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgpedic%2Fecto_shortuuid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgpedic%2Fecto_shortuuid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgpedic%2Fecto_shortuuid/lists"}