やりたいこと
主キー名をidから変えたい。intじゃなくてbigintにしたい。複合キーもできたらやってみたい。
なぜやりたい?
業務で使いたいなーと思ってるけど、
主キーにテーブル名をつけたい (例えばcustomer
テーブルの主キーをcustomer_id
とかcst_id
とかにしたい) 人がいたりするんで
この辺解決しないと抵抗されると思ったから。
ということでやってみます
customer
テーブルのキー名をid
からcst_id
に変更してみます
まずはphx.gen.html
でテンプレートもろもろ作成
※phoenixのプロジェクトは作成済みの想定です
$ mix phx.gen.html People Customer customers cst_name:string cst_email:string
migrationファイルの編集
priv/repo/migrations/<日付+タイムスタンプ>_create_customers.exs
を開いて、以下のように設定
def change do
create table(:customers, primary_key: false) do
add :cst_id, :integer, primary_key: true
add :cst_name, :string
add :cst_email, :string
timestamps()
end
end
create table(:customers, primary_key: false)
と
add :cst_id, :integer, primary_key: true
がポイントのようです。
デフォルトをOFFにして、かわりに任意のカラムをONにしているような感じでしょうか?
migrationの実行
mix ecto.migrate
schmeに設定追加
モジュールdefmodule <アプリ名>.<コンテキスト名>.Customer
を開いて編集します
<変更前>
schema "customers" do
field :cst_email, :string
field :cst_name, :string
timestamps()
end
<変更後>
@primary_key {:cst_id, :id, autogenerate: true}
@derive {Phoenix.Param, key: :cst_id}
schema "customers" do
field :cst_email, :string
field :cst_name, :string
timestamps()
end
@primary_key
と@derive
を追加しています。
@primary_key
は主キーフィールド名、タイプ、オプションとなっていて、デフォルトだと
{:id, :id, autogenerate: true}
となってるそうです。
https://hexdocs.pm/ecto/Ecto.Schema.html#module-schema-attributes
なんかこれだけでいけそうな雰囲気はしますが実際には
@derive
が必要みたいです。
https://hexdocs.pm/phoenix/Phoenix.Param.html
## ルーティングの追加
idがデフォルトの時と同じように
routes.ex
のscope "/",<アプリ名> do
の中に
resources "/customers", CustomerController
を追加するだけでOKです。
確認1
サーバーを立ち上げて
iex -S mix phx.server
にアクセスして追加、更新、表示、削除など、普通に出来ました。
確認2
本当にidが変わってるかテーブルを見てみます。
※SQLite3を使用しています。
使い方(手前味噌ですが):https://qiita.com/ko-tk/items/ab5e585d01bbf197c569
idがcst_id
になっており、インクリメントされていることがわかります。
以上。
じゃない。複合キーもやってみたいとか言いながら忘れてた。追記。
以下試してないけど、こんな感じで行けるんじゃなかろうか。
見つけてきたのが結構古いバージョンだから確かなことは言えませんが。。
参考:https://phoenixframework.readme.io/docs/ecto-custom-primary-keys
migrationファイル
def change do
create table(:customer, primary_key: false) do
add :cst_no, :string, primary_key: true
add :cst_type, :string, primary_key: true
add :name, :string
add :age, :integer
. . .
スキーマ
@primary_key false
schema "customer" do
field :cst_no, :string, primary_key: true
field :cst_type, :string, primary_key: true
field :name, :string
field :age, :integer
. . .