Появилась задача — использовать в качестве первичного ключа таблицы в проекте на Phoenix поле с UUID-ом. Как оказалось в Phoenix существует готовое решение, которое к тому же ещё и нормально работает и позволяет решить задачу с минимальными усилиями.
Итак первым делом очевидно нужно что-то добавить в миграцию — указыаем, что у нас нет первичного ключа, чтобы отключить его автогенерацию и добавляем соответствующее поле.
defmodule MyApp.Repo.Migrations.CreatePerson do
use Ecto.Migration
def change do
create table(:people, primary_key: false) do
add :id, :uuid, primary_key: true, default: fragment("uuid_generate_v4()")
add :name, :string
timestamps
end
end
end
Ну и затем нужно как-то сказать модели, чтобы в качестве идентификатора у нас генерировался UUID. Добавляем соответствующую конструкцию:
defmodule MyApp.Person do
use MyApp.Web, :model
# :binary_id генерируетс драйвером, по умолчанию для postgres это UUID
@primary_key {:id, :binary_id, autogenerate: true}
schema "people" do
field :name, :string
timestamps
end
...
Запускаем миграцию и видим, что поле у нас теперь типа uuid, и при сохранении модели первичный ключ генерируется как UUID.
При создании связей в таблице с использованием UUID первичного ключа необходимо добавить type: :uuid в параметры связи
defmodule MyApp.Repo.Migrations.CreateTask do
use Ecto.Migration
def change do
create table(:tasks) do
add :name, :string
add :person_id, references(:people, type: :uuid)
timestamps
end
end
end
Крайне удивлён. Всё прошло настолько гладко, что до сих пор не покидает ощущение какого-то подвоха. Но чорт побери — оно работает!
Комментарии