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:
Laravel 4 models have a built-in findOrNew method that does what you need:
$user = User::findOrNew($id);
Find or New based on primary key id
$user = User::findOrNew($id); // if exist then update else insert
$user->name= $data['full_name'];
$user->save();
First or New based on non-primary key single filed
// get the record where field_name=value else insert new record
$user = User::firstOrNew(['field_name'=>'value']);
$user->name= $data['full_name'];
$user->save();
First or New based on non-primary key multiple filed
// get the record where field_name1=value1 and field_name2=value2, else insert new record
$user = User::firstOrNew(['field_name1'=>'value1','field_name2'=>'value2']);
$user->name= $data['full_name'];
$user->save();
You can use firstOrCreate (It's working with Laravel 4.2)
$bucketUser = BucketUser::firstOrCreate([
'bucket_id' => '1',
'user_id' => '2',
]);
returns found instance or new instance.
Alternatively, in this case you can also use Laravel's function and search for id as an attribute, i.e.
$user = User::firstOrCreate(['id' => $id]);
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);
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
In Laravel 5:
There are two methods you may use to create models by mass assigning attributes: firstOrCreate
and firstOrNew
.
The firstOrCreate
method will attempt to locate a database record using the given column / value pairs. If the model can not be found in the database, a record will be inserted with the given attributes.
The firstOrNew
method, like firstOrCreate
will attempt to locate a record in the database matching the given attributes. However, if a model is not found, a new model instance will be returned. Note that the model returned by firstOrNew
has not yet been persisted to the database. You will need to call save manually to persist it:
// Retrieve the flight by the attributes, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve the flight by the attributes, or instantiate a new instance...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);