[Laravel] firstOrCreateで取得したレコードが既存か新規かを判別する方法

Laravel Laravel

はじめに

LaravelのfirstOrCreateメソッドは、指定した条件に合致するレコードを検索し、存在しなければ新たに作成する便利なメソッドです。

しかし、このとき「取得したレコードが既に存在していたものなのか、それとも新規に作成されたものなのか」を判別したいケースがあります。

この記事では、その方法を分かりやすく解説します。


firstOrCreateの基本的な使い方

firstOrCreateは次のように使用します。

$user = User::firstOrCreate(
    ['email' => 'test@example.com'], // 検索条件
    ['name' => 'Taro', 'password' => bcrypt('password')] // 新規作成時の値
);

この場合、

  • emailがtest@example.comのユーザーが存在すれば、そのレコードを返します
  • 存在しなければ、指定した値で新規作成します

新規作成か既存取得かを判別する方法

firstOrCreateの返り値であるEloquentモデルには、wasRecentlyCreated プロパティが用意されています。

使用例

$user = User::firstOrCreate(
    ['email' => 'test@example.com'],
    ['name' => 'Taro', 'password' => bcrypt('password')]
);

if ($user->wasRecentlyCreated) {
    echo "新規作成されました";
} else {
    echo "既存レコードを取得しました";
}

wasRecentlyCreatedプロパティとは

wasRecentlyCreatedは、Eloquentモデルが直近の操作で新規作成された場合にtrueを返します。

firstOrCreateだけでなく、createやsaveなどで新しく保存されたモデルでも利用可能です。


注意点

  • wasRecentlyCreatedは、そのモデルが直前の処理で作成されたかどうかのみを判断します
  • 一度モデルを再読み込み (refreshなど) すると、この値はfalseになります
  • updateOrCreateでも同様に利用可能です

まとめ

  • firstOrCreateで取得したレコードが新規作成か既存かはwasRecentlyCreatedで判別可能
  • 新規作成された場合はtrue、既存レコードの場合はfalse
  • 再読み込みするとfalseになるので注意

実用例

$user = User::firstOrCreate(
    ['email' => 'test@example.com'],
    ['name' => 'Taro', 'password' => bcrypt('password')]
);

if ($user->wasRecentlyCreated) {
    // 新規登録後の初期設定処理
} else {
    // 既存ユーザーへの別処理
}

これで、firstOrCreateの結果を正しく判別できるようになります。

著者

Webエンジニア歴30年、フリーランスバックエンドエンジニア。

PHP歴約30年(Laravel 7年・FuelPHP 5年・CakePHP・自作FW)、
JavaScript歴約20年(React・Vue各4年)。
AWS(EC2 / CloudFront / RDS / API Gateway など)・
GCP(BigQuery)を使ったバックエンド開発を中心に、
複数の事業会社・受託案件でシステム設計から実装・運用まで担当しています。

PHPがバージョン4の時代から書いており、
Laravelが普及する前のフレームワーク乱立期も経験しています。
「昔はこう書いていたが今はこう」という変遷を肌で知っているエンジニアとして、
単なるコマンドの使い方だけでなく、なぜそうするのかの背景まで伝えることを意識して書いています。

このブログでは、実務で実際に詰まった箇所・調べたこと・気づいたことを
そのまま記事にしています。誰かの「詰まり」が解決するきっかけになれば幸いです。

千原 耕司をフォローする

役にたったと思ったら応援をお願いします m(._.)m

Laravel
スポンサーリンク
シェアする
千原 耕司をフォローする
タイトルとURLをコピーしました