| この記事の要点 |
|
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 / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38