Laravel PHP

【Laravel/Eloquent】insertで一括挿入したレコードを取得する方法

開発環境

  • Laravel 9
  • PHP 8.1
  • GCP BigQuery

概要

LaravelのEloquentでDBに保存する方法として、

createinsertの2パターンがあります。

create

create一つずつ挿入、返り値は挿入したModelです

    /**
     * Save a new model and return the instance.
     *
     * @param  array  $attributes
     * @return \Illuminate\Database\Eloquent\Model|$this
     */
    public function create(array $attributes = [])

primary keyをオートインクリメントにしていた場合、nullで挿入すると、登録されたIDが返ってきます

// create前
[
    user_id => null,
    user_name => 'ユーザーA',
]

// create後
[
    user_id => 1, // 登録されたprimary key
    user_name => 'ユーザーA',
]

insert

insert複数行を挿入、することができます。

ただし、返り値がboolです。

   /**
     * Insert new records into the database.
     *
     * @param  array  $values
     * @return bool
     */
    public function insert(array $values)

この記事では、insertで複数行一括挿入して、挿入したレコードを取得する方法についてお伝えします

結論

   /**
     * @return array
     * @throws Exception
     */
    public function insert(): array
    {
        // insertする配列
        $requests = [
           [
              user_id => 1,
              user_name => 'ユーザーA',
           ],
           [
              user_id => 2,
              user_name => 'ユーザーB',
           ],
           [
              user_id => 3,
              user_name => 'ユーザーC',
           ],
         ];

        // step1:inset挿入
        $result = User::insert($requests);
        $result ?: throw new Exception('Failed to insert users');

        // step2:insertしたものを取得
        $inserted = User::query()
                ->orderByDesc('recommend_user_history_id')
                ->limit(count($requests))
                ->get();

        // step3:並び替え
        usort($insertedArray, fn ($a, $b) => $a->recommend_user_history_id <=> $b->recommend_user_history_id);
        return insertedArray;
    }
    

insert挿入

配列をinsertして、boolを$resultで受け取ります

$result = User::insert($requests);

insertが失敗した場合はエラーにして、"Failed to insert users"とログに出すようにします

 $result ?: throw new Exception('Failed to insert users');

IDを取得

ここがポイントです

オートインクリメントで一括挿入した場合、そのレコードは後ろに追加されていきます。

例えば10個レコードがあるテーブルに、5個追加すると、IDは11,12,13,14,15となるはずです。

したがって、insertで一括挿入したレコードを取得するためには、

後ろから、挿入したレコードの個数分だけ取得します

$inserted = User::query()
        ->orderByDesc('recommend_user_history_id')// 後ろから
        ->limit(count($requests))// 挿入した個数分だけ
        ->get();// 取得する

並び替え

ここはなくても処理上は問題ありません。

ただ、orderByDescで降順に取得しているため、IDが逆になって返ってきます。

気になる方は、ぜひご参考に。

usort($insertedArray, fn ($a, $b) => $a->recommend_user_history_id <=> $b->recommend_user_history_id);

upsort関数で並び替えますが、第一引数は配列にする必要があります。

そのため->toArray()でコレクションを配列にしてあげましょう。

upsortは並び替えでとても便利な関数です。

詳しい使い方はこちらをご覧ください。

-Laravel, PHP