LoginSignup
77
61

More than 1 year has passed since last update.

Laravel firstOrCreate と firstOrNewの違いと、create、newしたか判定する方法

Last updated at Posted at 2016-07-29

Laravelの、firstOrCreateとfirstOrNewの違いを調べました。
でも、まさしく、名前のままでした。

念のため、詳細は、
https://laravel.com/docs/5.1/eloquent

firstOrCreateは、実行時にレコードを作成

その名の通り、firstか、create。
実行時に、指定したパラメータを持ったレコードが無ければ、createします。
(外部キー制約がある場合、外部キーも渡さないとcreate時にexceptionになります)

firstOrCreate
// Eloquentを継承したAreaクラスがあったとする
$area = Area::firstOrCreate(['name' => '北海道']);

// wasRecentlyCreated を用いることで、今回のリクエストで作成されたことを判定できる
if ($area->wasRecentlyCreated) {

    // 既にcreateされているので、idなどのattributeにもアクセスできる

}

firstOrNewは、インスタンスを作成するだけ

newするだけなので、まだレコードとして記録されていません。
いい感じに処理したあとは、save()しましょう。DBにレコードが記録されます。
(レコードに外部キー制約がある場合、saveするより前に外部キーをつけてあげればOK。便利です。)

firstOrNew
// Eloquentを継承したAreaクラスがあったとする
$area = Area::firstOrNew(['name' => '北海道']);

if (!$area->exists) {
    // レコードが存在しないときは、existsがfalseになる
    // まだcreateされていないため、idなどのattributeにはアクセス出来ない
    ...
    ...
    // saveすることでcreateできる
    $area->save();
}

if ($area->wasRecentlyCreated) {
    // saveによって、新しくレコードが作られたことを判定できる
    ...
}

createされたかどうかの判定の仕方

wasRecentlyCreatedで判定することができます!

newされたものかどうかの判定の仕方

exists というプロパティが使えそうです(Laravel5.1のModel実装)。
これは、レコードが存在するかどうかを示すbool値です。このことから、firstOrNewの直後に、そのインスタンスがfirstで取れたものか、newされたものかをチェックする必要があるときには、使いやすいプロパティかなと感じます。

Laravel 5.1 未満の create, new判定

Lravel 5.1未満では、wasRecentlyCreatedは使用できませんでした。
そのため、私は以下のような方法で実装していました。

firstOrNew(Laravel5.1未満)
// Eloquentを継承したAreaクラスがあったとする
$area = Area::firstOrNew(['name' => '北海道']);

if (!$area->id) {

    // saveすることでcreateできる
    $area->save();
}

firstOrNewを使用して、取得したインスタンスにidが付与されているかどうかを確認することで、新規追加のデータかどうかを調べられます。しかし、Laravel 4.2でもexistsのプロパティがありました。こちらのほうが意図が伝わりやすい書き方になりそうです。
firstOrCreateの方では、おそらくレコードの新規追加をチェックできなさそうです。Createしてしまうと、idも付与されてしまいますので。idでできないとするならば、空のカラムあるなどのチェックとかなら、できそうですね。

77
61
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
77
61