The Ecto integration requires Ecto 3.12 or later within the 3.x series. Ecto remains optional when using Uniq for UUID generation, parsing, and formatting alone.

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

For many_to_many association you should add type: :uuid:

@primary_key {:id, Uniq.UUID, version: 7, autogenerate: true, type: :uuid}