[Laravel] firstOrCreate( ) とは?使い方を解説します!

SPONSORED LINK

使い方 (第1引数のみ)

$user = User::firstOrCreate([
    'name' => 'hoge',
    'email' => 'hoge@hoge.com',
]);

Illuminate\Database\Eloquent\Builder に定義されている関数なので,モデルから呼ぶことができます.

第1引数には,検索したいレコードのカラム名とその値を連想配列で渡します.

上の例だと,usersテーブルに name カラムが `hoge` で emialカラムが `hoge@hoge.com` のレコードを検索して,存在すれば first() で取得,存在しなければ save() します.

同じ値を持つレコードが存在するかどうかの確認とsave() をまとめてやってくれるので,コードが簡潔になりますね.

使い方 (第2引数を使う場合)

次は,第2引数も指定してみます.

第2引数には,新しくレコードを追加する場合に挿入する他のカラムの値を指定します.

下の例だと,agestatusにデフォルトの値ではなく,指定した値をレコードに挿入することができます.

$user = User::firstOrCreate([
    'name' => 'hoge',
    'email' => 'hoge@hoge.com',
], [
    'age' => 30,
    'status' => 10
]);

実は,第2引数を指定しなくても以下のようにすれば上のコードと同じ動作になりますが,第2引数を指定した方が見やすいですね.

$user = User::firstOrCreate([
    'name' => 'hoge',
    'email' => 'hoge@hoge.com',
]);
$user->age = 30;
$user->status = 10;
$user->save();

SPONSORED LINK

レコードが作成されたかどうかを判定する

自動でレコードが作成されるのはいいけれど,レコードが作成されたかどうかがわからないと不便な時がありますよね.そんなときは,$user->wasRecentlyCreatedを使います.

$user->wasRecentlyCreatedには,レコードを作成した場合にTrue,作成しなかった場合にFalseが入ります.たとえば,こんな使い方.

$user = User::firstOrCreate([
    'name' => 'hoge',
    'email' => 'hoge@hoge.com',
]);

if ($user->wasRecentlyCreated) {
    $user->age = 30;
    $user->status = 10;
    $user->save();
}

firstOrCreate() の定義を見てみよう

ここからは,ちょっと冒険です.

Illuminate/Database/Eloquent/Builder.phpに行って,関数の中身を見てみます.

まずは,テーブルから$attributeの条件を満たすレコードを検索します.そしてレコードが取得できれば,そのレコードをそのまま返し,レコードが取得できなかった場合は新しくレコードを作成する処理に入ります.

public function firstOrCreate(array $attributes, array $values = [])
{
    if (! is_null($instance = $this->where($attributes)->first())) {
        return $instance;
    }
    return tap($this->newModelInstance($attributes + $values), function ($instance) {
        $instance->save();
    });
}

これがレコードを作成する処理ですね.

tap($this->newModelInstance($attributes + $values), function ($instance) {
    $instance->save();
});

SPONSORED LINK

最後に

firstOrCreate()は思っていたよりも簡単な関数でした.難しそうな関数も実は普通に処理をしてるだけなんだなぁと気づけたのが今回の収穫です.


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です