Find or Create with Eloquent

eloquent, laravel, laravel-4, php

Solution

Below is the original accepted answer for: Laravel-4

There is already a method `findOrFail` available in `Laravel` and when this method is used it throws `ModelNotFoundException` on fail but in your case you can do it by creating a method in your model, for example, if you have a `User` model then you just put this function in the model

// Put this in any model and use
// Modelname::findOrCreate($id);
public static function findOrCreate($id)
{
    $obj = static::find($id);
    return $obj ?: new static;
}

From your controller, you can use

$user =  User::findOrCreate(5);
$user->first_name = 'John';
$user->last_name = 'Doe';
$user->save();

If a user with `id` of `5` exists, then it'll be updated, otherwise a new user will be created but the `id` will be `last_user_id + 1` (auto incremented).

This is another way to do the same thing:

public function scopeFindOrCreate($query, $id)
{
    $obj = $query->find($id);
    return $obj ?: new static;
}

Instead of creating a static method, you can use a `scope` in the Model, so the method in the `Model` will be `scopeMethodName` and call `Model::methodName()`, same as you did in the static method, for example

$user =  User::findOrCreate(5);

Update:

The `firstOrCreate` is available in `Laravel 5x`, the answer is too old and it was given for `Laravel-4.0` in `2013`.

In Laravel 5.3, the `firstOrCreate` method has the following declaration:

public function firstOrCreate(array $attributes, array $values = [])

Which means you can use it like this:

User::firstOrCreate(['email' => $email], ['name' => $name]);

User's existence will be only checked via email, but when created, the new record will save both email and name.

API Docs

Problem

I have recently started working with Laravel and Eloquent, and was wondering about the lack of a find or create option for models. You could always write, for example: ``` $user = User::find($id); if (!$user) { $user = new User; } ``` However, is there not a better way to find or create? It seems trivial in the example, but for more complex situations it would be really helpfully to either get an existing record and update it or create a new one.

Original source