目的
LaravelでDBテーブルの作成を行う中で、有名な「SQLアンチパターン」の中の1つ"IDリクワイアド"を避けるために、テーブルの主キー名をidから変更します。
IDリクワイアドについてはこちら
実装
例えば、新たに作るClientテーブルの主キーを client_id
にするとします。
php artisan make:migration create_clients_table
で生成したマイグレーションファイルを書き換えます。
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->bigIncrements('client_id'); // デフォルトの'id'から変更
$table->string('client_name');
$table->string('tel', 11);
$table->string('email')->nullable();
$table->timestamps();
});
}
こんな感じにして、php artisan migrate
を実行すると、主キーが company_id
となったclientsテーブルが作られます。
あとは登録機能実装して登録するだけ!
...
SQLSTATE[42703]: Undefined column: 7 ERROR: 列"id"は存在しません LINE 1: ..._at") values ($1, $2, $3) returning "id" ^ (SQL: insert into “clients" (“client_name”, "updated_at", "created_at") values (hoge, 2019-06-14 15:30:38, 2019-06-14 15:30:38) returning "id")
あれ...(´・ω・`)
migrationファイルの書き換えだけでは足りないようです。
解決
内部で主キーのカラム名がid以外許されていないのだろうか…などと思いながら調べていった結果、公式にちゃんと答えがありました。
[Laravel5.8 Eloquent:利用の開始]
(https://readouble.com/laravel/5.8/ja/eloquent.html)
主キー
Eloquentは更にテーブルの主キーがidというカラム名であると想定しています。この規約をオーバーライドする場合は、protectedのprimaryKeyプロパティを定義してください。
予想通り。しかもちゃんとオーバーライドも用意されてた(当たり前か)
というわけでEloquentモデルのClientクラスに以下の1行を追加します。
protected $primaryKey = 'client_id';
これで問題なく保存できるようになりました。
余談
今回取り上げたIDリクワイアドですが、SQLアンチパターンの中では賛否両論あるパターンのようです。
SQLアンチパターン「IDリクワイアド」の再検討
自分は単純にReadableなプログラムを目指す中で取り入れてみましたが、もう少し勉強して検討した方がよさそうですね。