php - Laravel firstOrCreate issues
I have some problems with checking if some value exists in database and if not then to create it and return id, but every time when I write something like:
$attribute = AttributeValue::where('value', $value)->firstOrCreate([
'value' => $value,
'attribute_id' => $relation->attribute_id,
'default_order' => $next
]);
It gives error for duplicate entry, like:
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'M' for key
'e_product_attributes_value_value_unique'
I also tried with firstOrNew, but it's not working good as well. Any ideas how to fix that?
Answer
Solution:
The most likely reason it's causing a unique key constraint error is because you're misusing firstOrCreate()
. Your query should be
$attribute = AttributeValue::firstOrCreate(
[
'value' => $value,
],
[
'attribute_id' => $relation->attribute_id,
'default_order' => $next,
]
);
Here's the source code for Eloquent Builder's .
/**
* Get the first record matching the attributes or create it.
*
* @param array $attributes
* @param array $values
* @return \Illuminate\Database\Eloquent\Model|static
*/
public function firstOrCreate(array $attributes = [], array $values = [])
{
if (! is_null($instance = $this->where($attributes)->first())) {
return $instance;
}
return tap($this->newModelInstance($attributes + $values), function ($instance) {
$instance->save();
});
}
As you can see, it roughly translates to
$attribute = AttributeValue::where('value', $value)->first();
if ($attribute === null) {
$attribute = AttributeValue::create([
'value' => $value,
'attribute_id' => $relation->attribute_id,
'default_order' => $next,
]);
}
Source