Customizing additional parameters in FirstOrCreate in Laravel 5.3

(This is part of a series of posts on New Features in Laravel 5.3.)

  1. Introducing Laravel Echo: An In-Depth Walk-Through
  2. The new $loop variable in Laravel 5.3
  3. Customizing additional parameters in FirstOrCreate in Laravel 5.3
  4. The new cache() global helper in Laravel 5.3
  5. New JSON-column where() and update() syntax in Laravel 5.3
  6. Advanced operations with Collection::where in Laravel 5.3
  7. Image dimension validation rules in Laravel 5.3
  8. Customizing pagination templates in Laravel 5.3
  9. 5.3 feature announcement notes from Laracon
  10. Routing changes in Laravel 5.3
  11. Introducing Laravel Scout
  12. Introducing Laravel Passport
  13. Introducing Mailables in Laravel 5.3
  14. Directory structure changes in Laravel 5.3
  15. The new Notification system in Laravel 5.3
  16. Update to queue workers in Laravel 5.3
  17. Using Vue in Laravel 5.3, with the Vue bootstrap and sample component
  18. Defining console commands via closure in Laravel 5.3 (coming soon)

More Laravel 5.3 goodies! This time, it's an update to the Eloquent firstOrCreate method.

If you've never used it before, you can pass an array of values to firstOrCreate and it will look up whether a record exists with those properties. If so, it'll return that instance; if not, it'll create it and then return the created instance.

Here's an example:

$tag = Tag::firstOrCreate(['slug' => 'matts-favorites']);

This is good. It's very useful. But.

What if the tag with the slug matts-favorites represents a tag with the label Matts favorites?

$tag = Tag::firstOrCreate(['slug' => 'matts-favorites', 'label' => 'Matts Favorites']);

OK, that worked well. But now, imagine this scenario: you want to create a tag with slug of matts-favorites and label of Matt's favorites unless there's already a tag with slug matts-favorites, in which case you just want that tag—even if it doesn't give you the label you want? Check it:

$tag = Tag::firstOrCreate(
    ['slug' => 'matts-favorites'],
    ['label' => "Matt's Favorites"]
);

We've specified that the Tag model should look up a tag where slug is matts-favorites and return it if so. And if not, create a new tag with slug matts-favorites and label Matt's Favorites, and return that. Bam. Beautiful.


Comments? I'm @stauffermatt on Twitter


Tags: laravel | laravel 5.3 | eloquent

Matt Stauffer headshot

Hi, I'm Matt Stauffer.

I'm partner & technical director at Tighten Co.

You can find me on Twitter at @stauffermatt


Like what you're reading?

I wrote an entire 450+ page book for O'Reilly: Laravel: Up and Running.

You can order the eBook or print book today.