Reputation: 570
let's say I have a following table: id | name | email | create_date | creator_id
When I'm using Laravel's firstOrCreate method it duplicates my records, because create_date and creator_id parameters are being changed on every call. Is there a way to disregard these fields while checking for an already existing record in DB?
Pseudo example might look like this: firstOrCreate(array('name'=>'test', 'email'=>'[email protected]'), $exceptionsArray('create_date', 'creator_id'))
Upvotes: 2
Views: 1669
Reputation: 2944
The firstOrCreate()
method accepts an array of attributes, and it's based on the existence of a record from those attributes that the record is either returned or created.
For instance:
| id | name | created_at |
| 1 | Joe | 2015-10-01 01:00:00 |
| 2 | Sam | 2015-10-01 01:00:00 |
| 3 | Ali | 2015-10-01 01:00:00 |
| 4 | Tom | 2015-10-01 01:00:00 |
$user = User::firstOrCreate(['name' => 'Joe']);
// $user = record with id 1
This is an existing user, because firstOrFail()
performs:
User::where('name', 'Joe')->first();
Next example:
$user = User::firstOrCreate(['name' => 'Joe', 'created_at' => '2015-10-01 01:00:00']);
// $user = record with id 1
This returns the user because under the hood the following query is performed:
User::where('name', 'Joe')->where('created_at', '2015-10-01 01:00:00')->first();
$user = User::firstOrCreate(['name' => 'Joe', 'created_at' => '2020-10-01 01:00:00']);
// $user = a brand new user, as the created_at time is different
What the firstOrCreate()
method does is check to see if a record exists with the attributes you pass it.
So, taking the last example, the reason it created a new record is because it evaluated:
User::where('name', 'Joe')->where('created_at', '2020-10-01 01:00:00')->first();
Which will of course fail.
In short, when using firstOrCreate
, don't pass a created_at
attribute as this is always created dynamically, and in many cases you may not want to include a creator_id
.
Upvotes: 3
Reputation: 1289
I don't know if this is an option for you but you could just use the exists() method on your query like this:
if (Model::where('name', '=', 'test')->where('email', '=', '[email protected]')->exists()) {
// do something
} else {
// add new record
}
Upvotes: 1