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