Phoenix

PhoenixでUUIDを自動生成する

この辺りを参考にしました。

UUIDs as primary keys in Phoenix (with Ecto and Elixir)(medium)

How to customize id of Phoenix(stackoverflow)

プロジェクト作成

mix phx.new uuid_auto_sample

# 終わったら、
cd uuid_auto_sample

データベース作成

psqlは起動しておいてください。

mix ecto.create

plug_cowboy追加

idとは関係ありませんが、今私が使っているバージョンだと、このエラーが出るので対処しておきます。(qiitaの情報

mix.exsに、パッケージを追加

# 一部だけ載せています
  defp deps do
    [
      {:phoenix, "~> 1.3.4"},
      {:phoenix_pubsub, "~> 1.0"},
      {:phoenix_ecto, "~> 3.2"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 2.10"},
      {:phoenix_live_reload, "~> 1.0", only: :dev},
      {:gettext, "~> 0.11"},
      {:cowboy, "~> 1.0"}, # <-- カンマ追加(よく忘れるので)
      {:plug_cowboy, "~> 1.0"} # <-- これを追加
    ]
  end

依存パッケージインストール

mix deps.get

動かしてみる

一旦、起動できるか確認しておきます。

mix phx.server

localhost:4000にアクセスしてWelcome to Phoenixというページが出ていれば良い。

テーブル定義

id, email, nameのフィールドを持つユーザーテーブルを作ります。
ここではidを含めません。

mix phx.gen.json Users User users email:string name:string

以下のようなメッセージが出ると思います。

Add the resource to your :api scope in lib/uuid_auto_sample_web/router.ex:

    resources "/users", UserController, except: [:new, :edit]


Remember to update your repository by running migrations:

    $ mix ecto.migrate

言われた通り、lib/uuid_auto_sample_web/router.exにリソースを追加します。mix ecto.migrateはやらないでください。

# 一部だけ載せています
  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", UuidAutoSampleWeb do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end

  # 以下の4行追加
  scope "/api", UuidAutoSampleWeb do
    pipe_through :api
    resources "/users", UserController, except: [:new, :edit]
  end
end

Ecto.UUIDを自動生成するようにスキーマ修正

lib/uuid_auto_sample/users/user.exに2行します。最初に紹介したmediumなどの記事だと、:idの型を:binary_idにしていますが、今はEcto.UUIDが使えるので、それにします。
中の仕組みがまだよくわかっていませんが、UUID4を自動生成してくれるようになります。おそらくどこかでEcto.UUID.generateが呼ばれているんだとは思います。

# 一部だけ載せています
defmodule UuidAutoSample.Users.User do
  use Ecto.Schema
  import Ecto.Changeset


  @primary_key {:id, Ecto.UUID, autogenerate: true} # <-- これを追加
  @derive {Phoenix.Param, key: :id} # <-- これも追加
  schema "users" do
    field :email, :string
    field :name, :string

    timestamps()
  end

マイグレーションを修正

create tableで勝手にintのidが生成されないように(primary_key: falseのところ)、そして、自分で作ったuuidがprimary keyとして使われるように(行追加したところ)修正します。

defmodule UuidAutoSample.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users, primary_key: false) do # <-- ここ修正
      add :id, :uuid, primary_key: true # <-- この行を追加
      add :email, :string
      add :name, :string

      timestamps()
    end

  end
end

以上で完了です。

マイグレーション

mix ecto.migrate

試す

phoenixを起動して、ユーザー登録をしてみましょう。

mix phx.server

別のシェルを立ち上げて、以下のようにpostでユーザー追加してみます。

curl -H 'Content-Type: application/json' -X POST -d '{"user": {"email":"neo@matrix.com", "name": "Thomas A. Anderson"}}' localhost:4000/api/users

# レスポンス
{"data":{"name":"Thomas A. Anderson","id":"304ec98a-7cd4-4c28-9aa8-80ad2e1c8ee5","email":"neo@matrix.com"}}

このようにレスポンスが返ってくれば、成功です。もちろんuuidなので、idの文字列は上記と違うはずです。

curlでGETするか、localhost:4000/api/usersにアクセスすると、登録されたユーザーのjsonデータを確認できます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です