For what are Sqids and why would you want to use them I recommend looking at the linked website. But basically it is a pretty presentation for integer type. You might prefer having url like /rooms/DcHPs
over /rooms/151
or /rooms/48922bf6-c418-4023-a478-0cca4dd04e68
.
The library consists of a single module AshSqids.Type
that provides Ash.Type
implementation.
Add to the deps, get deps (mix deps.get
), compile them (mix deps.compile
).
def deps do
[
{:ash_sqids, "~> 0.0.1"},
]
end
Define a module that will represent a Sqid type and use AshSqids.Type
in it. Provide configuration for it in config :ash_sqids, :opts
. And then use it as type in attributes and arguments.
# lib/example/posts/resources/comment.ex
defmodule Example.Posts.Comment do
use Ash.Resource, data_layer: AshPostgres.DataLayer
# 1) define a type module
defmodule Id, do: use(AshSqids.Type)
attributes do
# 2) use it as an attribute type
integer_primary_key :id, type: Id
# ...
end
relationships do
# 3) use as `attribute_type` in `belongs_to` like this
belongs_to :post, Example.Posts.Post, attribute_type: Example.Posts.Post.Id
end
end
As shown if you want to use it as a primary key (main use case) then add integer_primary_key
with type
option.
And don't forget attribute_type
in belongs_to
for references to a resource with sqids.
Here is how mentioned config is supposed to look:
# config/config.exs
import Config
config :ash_sqids, :opts, [
{Example.Posts.Comment.Id, []}, # use default options
{Example.Posts.Post.Id, min_length: 7} # some custom values
]
Options are passed into Sqids.new!
and at the time of writing there are three options there -
alphabet
, min_length
and blocklist
.
It is better to provide alphabet. It can be a default one - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
- but just shuffled.
use AshSqids.Type
accepts optional config
option that allows you to reuse configurations.
So if in the example we wanted for comments ids and posts ids to be in the same style then we could do it like this:
# `config` is an atom (defaulting to a module name) that will be used as a key
# to look up Sqids options from `config :ash_sqids, :opts`
defmodule Id, do: use(AshSqids.Type, config: Example.Posts.Post.Id)
AshSqids.Type
provides implementation for following protocols:
String.Chars
- so"#{id}"
results in a sqid string.Jason.Encoder
- same, returns a sqid string.Inspect
- with the format of#Example.Posts.Comment.Id<1, "Uk">
.
Sqids - website, github, elixir library.
Ash - website, github, Ash.Type
docs.