| この記事の要点 |
|
Eloquent の主キーの既定値
Laravel の Eloquent モデルは、何も設定しなければ主キーを次のように扱います。テーブルがこの形なら、モデルに主キーの設定を書く必要はありません。
| プロパティ | 既定値 | 意味 |
|---|---|---|
$primaryKey | 'id' | 主キーのカラム名 |
$incrementing | true | DB の自動採番(AUTO_INCREMENT など)で値が決まるか |
$keyType | 'int' | 主キーの型('int' か 'string') |
マイグレーションの $table->id(); は「id という名前の自動採番の BIGINT 主キー」を作るので、この既定値とそのまま一致します。
主キーのカラム名を変える($primaryKey)
Laravel のモデルに主キーを指定するには、以下の様に $primaryKey にカラム名を代入します。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $primaryKey = 'user_id';
}
User::find(10) は WHERE user_id = 10 になり、リレーションの既定の外部キーや $user->getKey() もこの設定に従います。古い Laravel(7 以前)ではモデルの名前空間が App でしたが、Laravel 8 以降は App\Models が標準です。
自動採番しない主キー($incrementing)
主キーがインクリメントしない(社員番号などをアプリ側で決める)場合は $incrementing を false とします。
class Employee extends Model
{
protected $primaryKey = 'employee_code';
public $incrementing = false;
protected $keyType = 'string';
}
// 保存時に自分で主キーを入れる
Employee::create(['employee_code' => 'E0001', 'name' => '山田']);
$incrementing が true のままだと、INSERT 後に Laravel が DB の「最後に採番された ID」を主キーに上書きしようとします。自動採番でないテーブルでは 0 などの値が入り、直後の $model->employee_code や save() による更新が意図しない動きになります。
文字列の主キー($keyType)
主キーが文字列なのに $keyType を 'string' にしないと、$incrementing = true の状態では主キーが整数にキャストされ、'ABC' が 0 になるといった現象が起きます。文字列の主キーでは $incrementing = false と $keyType = 'string' をセットで書くのが安全です。
UUID / ULID を主キーにする
UUID や ULID を主キーにする場合は、専用のトレイトを使うと $incrementing / $keyType の設定と、作成時の値の自動生成をまとめて行ってくれます。
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
use HasUuids; // ULID なら HasUlids
}
// マイグレーション
Schema::create('orders', function (Blueprint $table) {
$table->uuid('id')->primary(); // ULID なら $table->ulid('id')->primary();
$table->timestamps();
});
複合主キーは Eloquent では使えない
旧版の本記事では次のように $primaryKey に配列を指定する方法を紹介していましたが、Eloquent は複合主キーをサポートしていません(公式ドキュメントにも明記されています)。
// これは正しく動かない
protected $primaryKey = ['user_id', 'user_type'];
この指定でも一部の取得処理は動いたように見えることがありますが、find()、save() による更新、delete()、リレーションなど、主キーを 1 つの値として扱う処理でエラーや誤動作になります。複合キーのテーブルを扱う方法は次のとおりです。
- サロゲートキーを追加する(推奨):
$table->id();で自動採番の主キーを持たせ、元の複合キーには複合ユニーク制約を付ける - モデルの主キーは片方だけにし、更新・削除はクエリビルダで条件を書く:
DB::table('user_roles')->where('user_id', 1)->where('user_type', 'admin')->update([...]) - 多対多の中間テーブルであれば、モデルを作らず
belongsToManyのattach()/detach()/sync()で操作する
// 1. のマイグレーション例
Schema::create('user_roles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('user_type');
$table->unique(['user_id', 'user_type']); // 元の複合キーは一意制約で守る
});
DB 側で複合主キーを作るだけなら、マイグレーションで $table->primary(['user_id', 'user_type']); と書けます。制約が付かないのは Eloquent モデルの側だという点に注意してください。
確認方法
php artisan model:show Userで、モデルが認識している主キー・テーブル・カラムの情報を一覧できるphp artisan tinkerで(new App\Models\User)->getKeyName()を実行し、主キー名を確認する- 保存直後に
dump($model->getKey())で、期待した値(0 になっていないか)を確認する
関連
- MySQL AUTO_INCREMENT 完全ガイド
- SQL CREATE TABLE|主キー・外部キー
- SQL 制約まとめ|NOT NULL・UNIQUE・主キー・外部キー・CHECK
- 【MySQL】ALTER TABLE 文による AUTO_INCREMENT の追加と確認方法
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09