View Source Using With Ecto
You can use the type provided by this library in lieu of Ecto.UUID
, simply use Uniq.UUID
where you would use Ecto.UUID
, and specify :binary
or :string
as the type of the column
in your migrations, depending on what parameters you pass to the type. By default, with no
parameters, the UUID will be stored as :binary
, and loaded in :default
format. You can control
this behaviour by using the :dump
and :format
options to control what format is used for persistence
and in-memory, respectively. The format atoms are the same as you can pass elsewhere, i.e. :raw
, :default
,
:hex
, :urn
, and :slug
. All of them but :raw
are printable strings, while :raw
is a binary-encoded
format.
If you wish to use autogenerated UUIDs with Ecto, you have a couple of options:
# Generate UUIDv4 primary keys
@primary_key {:id, Uniq.UUID, autogenerate: true}
schema "foo" do
...
end
# Generate primary keys using UUIDs of a specific version
# NOTE: To autogenerate UUIDs using version 3 or 5, see below
@primary_key {:id, Uniq.UUID, version: 1, autogenerate: true}
schema "foo" do
...
end
# Generate primary keys using, version 3 or 5, which are namespaced
# NOTE: Uniq generates 8 bytes of cryptographically strong random data for the name, but
# you must provide a custom namespace in which these names are allocated, as the predefined
# namespaces are not a good fit for random generated ids.
@namespace Uniq.UUID.uuid5(:dns, "foo.example.com", :raw)
@primary_key {:id, Uniq.UUID, version: 5, namespace: @namespace, autogenerate: true}
schema "foo" do
...
end
# The same rules as above can be used to autogenerate UUIDs for any field, not just primary keys
schema "foo" do
field :uuidv4, Uniq.UUID, autogenerate: true
field :uuidv1, Uniq.UUID, version: 1, autogenerate: true
# This field will be dumped to a 36-byte printable string format, and loaded into a 22-byte base64-encoded string
field :uuidv3, Uniq.UUID, version: 3, namespace: @namespace, format: :slug, dump: :default, autogenerate: true
end
To use UUIDs for all keys, you can do something like this:
# Define your global schema defaults in a module
defmodule MyApp.Schema do
defmacro __using__(_) do
quote do
use Ecto.Schema
@primary_key {:id, Uniq.UUID, autogenerate: true}
@foreign_key_type Uniq.UUID
end
end
end
# Then use that module anywhere that you would use `Ecto.Schema` to apply those defaults
defmodule MyApp.Comment do
use MyApp.Schema
schema "comments" do
belongs_to :post, MyApp.Post
end
end