LoginSignup
30
27

More than 3 years have passed since last update.

Laravelで主キー名を変更する際の注意点

Posted at

目的

LaravelでDBテーブルの作成を行う中で、有名な「SQLアンチパターン」の中の1つ"IDリクワイアド"を避けるために、テーブルの主キー名をidから変更します。
IDリクワイアドについてはこちら

実装

例えば、新たに作るClientテーブルの主キーを client_id にするとします。
php artisan make:migration create_clients_table で生成したマイグレーションファイルを書き換えます。

2019_06_14_150035_create_clients_table.php
    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:利用の開始

主キー
Eloquentは更にテーブルの主キーがidというカラム名であると想定しています。この規約をオーバーライドする場合は、protectedのprimaryKeyプロパティを定義してください。

予想通り。しかもちゃんとオーバーライドも用意されてた(当たり前か)

というわけでEloquentモデルのClientクラスに以下の1行を追加します。

Client.php
protected $primaryKey = 'client_id';

これで問題なく保存できるようになりました。

余談

今回取り上げたIDリクワイアドですが、SQLアンチパターンの中では賛否両論あるパターンのようです。
SQLアンチパターン「IDリクワイアド」の再検討

自分は単純にReadableなプログラムを目指す中で取り入れてみましたが、もう少し勉強して検討した方がよさそうですね。

30
27
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
27