Skip to content

oyeb/ecto_identifier

Repository files navigation

EctoIdentifier 🎯

When UUID is not enough!

codecov Build Status

Provides some custom Ecto types to work with identifier fields that are generated using:

  1. nanoids (Ecto.Nanoid)

Full docs available on hexdocs.pm

Ecto.Nanoid

Nanoid are as safe and sound as UUIDs, but more compact. Check them out in real life! 🌈

The type defines an autogenerate/0 that can generate a nanoid for you at "insert-time". You don't have to worry about adding the field to your changeset cast/validate_required (just like those auto-generated timestamps)!

defmodule Post do
  use Ecto.Schema
  alias Ecto.Nanoid

  schema "posts" do
    field(:number, Ecto.Nanoid, autogenerate: true)
    field(:data, :string)
  end
end

And voila!

iex> changeset = Post.changeset(%Post{}, %{data: "the answer to everything"})
iex> changeset.changes.number
nil                                         # coz it's autogenerated!
iex> a_tough_one = Repo.insert!(changeset)
iex> %Post{
  id: 42,
  number: "swv-u7bIyewzBFOKuFbbD",          # there we have it!
}

If you pass in a :number in the params, a nanoid will not be autogenerated for you. For more juicy details see Ecto.Schema.

Why a "type"

Well, to make Ecto compute the ID only at "insert-time", you gotta define an autogenerate/0 for that field's type. Which means, this nanoid field needs to be of a custom Ecto.Type, ala Ecto.Nanoid.

Can I use this as my primary key?

Well of course! Example:

@primary_key {:id, :string, autogenerate: {Ecto.Nanoid, :autogenerate, []}}
schema "users" do
  field :email, :string
  field :name, :string

  timestamps()
end
def change do
  create table(:users, primary_key: false) do
  add :id, :string, primary_key: true
  add :email, :string
  add :name, :string

  timestamps()
end

end

How should I configure the Nanoids?

You can use config.exs to configure all the nanoids of your application.

Make sure you recompile nanoid in the relevant "environment" (see this thread)

Ecto.Hashids

Coming shortly folks! Maybe not... Take a look at peek-travel/ecto_hashids.

Installation

The package can be installed by adding ecto_identifier to your list of dependencies in mix.exs:

def deps do
  [
    {:ecto_identifier, "~> 0.2.0"}
  ]
end

License

Copyright 2018-2021 Ananya Bahadur

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.