Find or Create with Eloquent
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
First Or Create
firstOrCreate()
checks for all the arguments to be present before it finds
a match. If not all arguments match, then a new instance of the model will be created.
If you only want to check on a specific field, then use firstOrCreate(['field_name' => 'value'])
with only one item in the array. This will return the first item that matches, or create a new one if not matches are found.
The difference between firstOrCreate()
and firstOrNew()
:
firstOrCreate()
will automatically create a new entry in the database if there is not match found. Otherwise it will give you the matched item.firstOrNew()
will give you a new model instance to work with if not match was found, but will only be saved to the database when you explicitly do so (callingsave()
on the model). Otherwise it will give you the matched item.
Choosing between one or the other depends on what you want to do. If you want to modify the model instance before it is saved for the first time (e.g. setting a name
or some mandatory field), you should use firstOrNew()
. If you can just use the arguments to immediately create a new model instance in the database without modifying it, you can use firstOrCreate()
.
Where is the create method for Eloquent Model?
Eloquent Model uses magic methods (__call, __callStatic) to pass calls through to the Eloquent Builder class. Therefore, Model::create() is actually passing the call to the Builder::create() method.
However, if you investigate that method, it is basically the same as calling:
$model = new Model($attributes);
$model->save();
This mixin of the (Query) Builder via passthrough is what allows you to use query methods like Model::where()
Eloquent: access model relation or create new
As of Laravel 5.3.23, there is a new withDefault
method added to HasOne
relationships that should help with this.
In your example, your user
model would have the following relationship:
public function appUser() {
return $this->hasOne(appUser::class)->withDefault();
}
What this will do is, if there is no related record in the database, it will return a new instance of the related (appUser
) class. So, your code would end up looking like:
$user = user::find($userID);
// if user has an appuser, $user->appUser will return it;
// otherwise, it will return a new instance of your appUser model
$user->appUser->column = $value;
$user->appUser()->save();
Creating and Update Laravel Eloquent
Here's a full example of what "lu cip" was talking about:
$user = User::firstOrNew(array('name' => Input::get('name')));
$user->foo = Input::get('foo');
$user->save();
Below is the updated link of the docs which is on the latest version of Laravel
Docs here: Updated link
Laravel Eloquent Query: Using WHERE with OR AND OR?
Make use of Logical Grouping (Laravel 7.x/4.2). For your example, it'd be something like this:
Model::where(function ($query) {
$query->where('a', '=', 1)
->orWhere('b', '=', 1);
})->where(function ($query) {
$query->where('c', '=', 1)
->orWhere('d', '=', 1);
});
Eloquent: find() and where() usage laravel
Your code looks fine, but there are a couple of things to be aware of:
Post::find($id);
acts upon the primary key, if you have set your primary key in your model to something other than id
by doing:
protected $primaryKey = 'slug';
then find
will search by that key instead.
Laravel also expects the id
to be an integer, if you are using something other than an integer (such as a string) you need to set the incrementing property on your model to false:
public $incrementing = false;
How to implement search with contains using Eloquent
So the easiest way to achieve this is to use Eloquent Macros:
use Illuminate\Database\Eloquent\Builder;
// ...
Builder::macro('whereLike', function(string $attribute, string $searchTerm) {
return $this->orWhere($attribute, 'LIKE', "%{$searchTerm}%");
});
Now you can search Model like:
User::query()
->whereLike('name', $searchTerm)
->whereLike('email', $searchTerm)
->get();
More on the subject on: https://freek.dev/1182-searching-models-using-a-where-like-query-in-laravel
and
https://tighten.co/blog/the-magic-of-laravel-macros
Related Topics
Replace the Last Comma with an & Sign
Remove Double-Quotes from a JSON_Encoded String on the Keys
Any Preg_Match() to Extract Image Urls from Text
Symfony & Guard: "The Security Token Was Removed Due to an Accountstatusexception"
Setting $_Session Doesn't Work on Localhost Using Xampp
PHP String Concatenation - "$A $B" VS $A . " " . $B - Performance
Html2Pdf in PHP - Convert Utilities & Scripts - Examples & Demos
Calling a Controller Function in Another Controller in Codeigniter
PHP Class Not Found When Using Namespace
Can Mongodb and Its Drivers Preserve the Ordering of Document Elements
Add Custom Columns to Admin Products List in Woocommerce 3
How to Access MySQLi Connection in Another Class on Another Page
JavaScript or Jquery Doesn't Work in Dynamically Generated Content
PHP String Comparasion to 0 Integer Returns True
Change "Billing Details" Text to "Shipping Details" on Woocommerce Checkout Page
Set Multiple='False' in a Form in a Many to Many Relation Symfony2