DEV Community

Morcos Gad
Morcos Gad

Posted on • Updated on

firstOrNew, firstOrCreate, firstOr, updateOrCreate and sole methods - Laravel

I found some very interesting methods that may help you in writing code in your old projects and wanted to share them with you.

  • firstOrNew

The firstOrNew method is really useful for finding the first Model that matches some constraints or making a new one if there isn’t one that matches those constraints

$user = User::where('email', request('email'))->first();

if ($user === null) {
    $user = new User(['email' => request('email')]);
}

$user->name = request('name');
$user->save()

//firstOrNew
$user = User::firstOrNew(['email' =>  request('email')]);

$user->name = request('name');
$user->save()
Enter fullscreen mode Exit fullscreen mode
  • firstOrCreate

The firstOrCreate method is very similar to the firstOrNew method. It tries to find a model matching the attributes you pass in the first parameter. If a model is not found, it automatically creates and saves a new Model after applying any attributes passed in the second parameter

$user = User::firstOrCreate(
    ['email' =>  request('email')],
    ['name' => request('name')]
);
// No call to $user->save() needed
Enter fullscreen mode Exit fullscreen mode
  • firstOr

I recently found the firstOr method while source-diving. The firstOr method retrieves the first Model from a query, or if no matching Model is found, it will call a callback passed. This can be really useful if you need to perform extra steps when creating a user or want to do something other than creating a new user

$user = User::where('email', request('email'))->firstOr(function () {
    $account = Account::create([ //... ]);

    return User::create([
        'account_id' => $account->id,
        'email' => request('email'),
    ]);
});
Enter fullscreen mode Exit fullscreen mode
  • updateOrCreate

The updateOrCreate method attempts to find a Model matching the constraints passed as the first parameter. If a matching Model is found, it will update the match with the attributes passed as the second parameter. If no matching Model is found a new Model will be created with both the constraints passed as the first parameter and the attributes passed as the second parameter

$user = User::where('email', request('email'))->first();

if ($user !== null) {
    $user->update(['name' => request('name')]);
} else {
    $user = User::create([
      'email' => request('email'),
      'name' => request('name'),
    ]);
}

//updateOrCreate
$user = User::updateOrCreate(
    ['email' =>  request('email')],
    ['name' => request('name')]
);
Enter fullscreen mode Exit fullscreen mode
  • sole

At first we see the first() or get() methods

// All the records that match the query
Book::where('title', 'like', '%War%')->get();
/*
Illuminate\Database\Eloquent\Collection {#4264
 all: [
   App\Models\Book {#4209
     id: 1,
     title: "War of the Worlds",
     .....
   },
 ],
}
*/

// Get the first record in the query
// Even if the query has multiple matches, return the first one
Book::where('title', 'like', '%War%')->first();

/*
=> App\Models\Book {#4210
     id: 1,
     title: "War of the Worlds",
     ....
   }
*/
Enter fullscreen mode Exit fullscreen mode

The get() and first() methods are fairly common in Laravel apps, however, sole() is useful when you expect and want to guarantee the existence of one and only one record

Book::where('title', 'like', '%War%')->sole();
/*
App\Models\Book {#3647
  id: 1,
  title: "War of the Worlds",
  ....
}
*/
Enter fullscreen mode Exit fullscreen mode

If we don’t have a record in the database table, we can expect the ModelNotFoundException thrown

Book::where('title', 'like', '%The War')->sole();
// => Illuminate\Database\Eloquent\ModelNotFoundException
Enter fullscreen mode Exit fullscreen mode

If we have more than a single record in the database table, we also get an exception, but this time it’s the MultipleRecordsFoundException

// Create a second title with the word `War` in it.
Book::create([
    'title' => 'War and Peace',
    'summary' => 'Example summary'
]);

Book::where('title', 'like', '%War%')->sole();
// => Illuminate\Database\MultipleRecordsFoundException
Enter fullscreen mode Exit fullscreen mode

https://laravel-news.com/firstornew-firstorcreate-firstor-updateorcreate
https://laravel-news.com/understanding-the-sole-query-builder-method
I hope you enjoyed these methods as much as I did.

Discussion (0)